diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index 6f5fe9623b319..8acae3ff0144b 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -716,6 +716,7 @@ function(add_libswift name) set(libswift_compile_options "-Xfrontend" "-validate-tbd-against-ir=none" "-Xfrontend" "-enable-cxx-interop" + "-Xfrontend" "-disable-llvm-verify" "-Xcc" "-UIBOutlet" "-Xcc" "-UIBAction" "-Xcc" "-UIBInspectable") if(CMAKE_BUILD_TYPE STREQUAL Debug) @@ -778,7 +779,18 @@ function(add_libswift name) "-emit-module-path" "${build_dir}/${module}.swiftmodule" "-parse-as-library" ${sources} "-wmo" ${libswift_compile_options} - "-I" "${SWIFT_SOURCE_DIR}/include/swift" + "-I" "${CMAKE_SOURCE_DIR}/include/swift" + # The Swift source header includes: + "-I" "${CMAKE_SOURCE_DIR}/include" + # LLVM and Clang source header includes: + "-I" "${LLVM_MAIN_SRC_DIR}/../clang/include" + "-I" "${LLVM_MAIN_INCLUDE_DIR}" + # Swift build includes: + "-I" "${CMAKE_BINARY_DIR}/include" + # LLVM and Clang build includes: + "-I" "${LLVM_BINARY_DIR}/tools/clang/include" + "-I" "${LLVM_BINARY_DIR}/include" + # libSwift build includes: "-I" "${build_dir}" COMMENT "Building libswift module ${module}") diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h index b32dc943ff5c8..f04d64f50dd20 100644 --- a/include/swift/ABI/Metadata.h +++ b/include/swift/ABI/Metadata.h @@ -1518,6 +1518,11 @@ struct TargetStructMetadata : public TargetValueMetadata { } bool isCanonicalStaticallySpecializedGenericMetadata() const { + // Struct metadata is used for foreign reference types, in which case the + // descriptor is not a struct descriptor. + if (!llvm::isa>(this->Description)) + return false; + auto *description = getDescription(); if (!description->isGeneric()) return false; diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index cbd6503dd9dee..0551dc2119732 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -28,6 +28,7 @@ #include "swift/AST/GenericParamKey.h" #include "swift/AST/IfConfigClause.h" #include "swift/AST/LayoutConstraint.h" +#include "swift/AST/ReferenceCounting.h" #include "swift/AST/StorageImpl.h" #include "swift/AST/TypeAlignments.h" #include "swift/AST/TypeWalker.h" @@ -37,10 +38,10 @@ #include "swift/Basic/Compiler.h" #include "swift/Basic/Debug.h" #include "swift/Basic/InlineBitfield.h" +#include "swift/Basic/Located.h" #include "swift/Basic/NullablePtr.h" #include "swift/Basic/OptionalEnum.h" #include "swift/Basic/Range.h" -#include "swift/Basic/Located.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/TrailingObjects.h" #include @@ -3900,7 +3901,8 @@ class ClassDecl final : public NominalTypeDecl { /// /// \see getForeignClassKind bool isForeign() const { - return getForeignClassKind() != ForeignKind::Normal; + return getForeignClassKind() != ForeignKind::Normal || + const_cast(this)->isForeignReferenceType(); } /// Whether the class is (known to be) a default actor. @@ -3935,9 +3937,22 @@ class ClassDecl final : public NominalTypeDecl { bool isNativeNSObjectSubclass() const; /// Whether the class uses the ObjC object model (reference counting, - /// allocation, etc.) instead of the Swift model. - bool usesObjCObjectModel() const { - return checkAncestry(AncestryFlags::ObjCObjectModel); + /// allocation, etc.), the Swift model, or has no reference counting at all. + ReferenceCounting getObjectModel() { + if (isForeignReferenceType()) + return ReferenceCounting::None; + + if (checkAncestry(AncestryFlags::ObjCObjectModel)) + return ReferenceCounting::ObjC; + + return ReferenceCounting::Native; + } + + LayoutConstraintKind getLayoutConstraintKind() { + if (getObjectModel() == ReferenceCounting::ObjC) + return LayoutConstraintKind::Class; + + return LayoutConstraintKind::NativeClass; } /// Returns true if the class has designated initializers that are not listed @@ -4059,6 +4074,11 @@ class ClassDecl final : public NominalTypeDecl { bool hasKnownSwiftImplementation() const { return !hasClangNode(); } + + /// Used to determine if this class decl is a foriegn reference type. I.e., a + /// non-reference-counted swift reference type that was imported from a C++ + /// record. + bool isForeignReferenceType(); }; /// A convenience wrapper around the \c SelfReferencePosition::Kind enum. diff --git a/include/swift/AST/ReferenceCounting.h b/include/swift/AST/ReferenceCounting.h index 3eaf4a1acf788..26bf440ef3284 100644 --- a/include/swift/AST/ReferenceCounting.h +++ b/include/swift/AST/ReferenceCounting.h @@ -29,6 +29,10 @@ enum class ReferenceCounting : uint8_t { /// Blocks are always ObjC reference counting compatible. ObjC, + /// The object has no reference counting. This is used by foreign reference + /// types. + None, + /// The object uses _Block_copy/_Block_release reference counting. /// /// This is a strict subset of ObjC; all blocks are also ObjC reference diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h index 687070e5a4e8c..467753c4df00d 100644 --- a/include/swift/AST/Type.h +++ b/include/swift/AST/Type.h @@ -488,6 +488,8 @@ class CanType : public Type { NominalTypeDecl *getAnyNominal() const; GenericTypeDecl *getAnyGeneric() const; + bool isForeignReferenceType(); // in Types.h + CanType getOptionalObjectType() const { return getOptionalObjectTypeImpl(*this); } diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 5db9749bd73be..fa60d34bdb277 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -811,8 +811,8 @@ class alignas(1 << TypeAlignInBits) TypeBase /// If this is a class type or a bound generic class type, returns the /// (possibly generic) class. - ClassDecl *getClassOrBoundGenericClass(); - + ClassDecl *getClassOrBoundGenericClass() const; + /// If this is a struct type or a bound generic struct type, returns /// the (possibly generic) class. StructDecl *getStructOrBoundGenericStruct(); @@ -820,7 +820,10 @@ class alignas(1 << TypeAlignInBits) TypeBase /// If this is an enum or a bound generic enum type, returns the /// (possibly generic) enum. EnumDecl *getEnumOrBoundGenericEnum(); - + + /// If this is a class, check if this class is a foreign reference type. + bool isForeignReferenceType(); + /// Determine whether this type may have a superclass, which holds for /// classes, bound generic classes, and archetypes that are only instantiable /// with a class type. @@ -6175,7 +6178,7 @@ inline bool TypeBase::canDynamicallyBeOptionalType(bool includeExistential) { return isArchetypeOrExistential && !T.isAnyClassReferenceType(); } -inline ClassDecl *TypeBase::getClassOrBoundGenericClass() { +inline ClassDecl *TypeBase::getClassOrBoundGenericClass() const { return getCanonicalType().getClassOrBoundGenericClass(); } @@ -6239,8 +6242,6 @@ inline GenericTypeDecl *TypeBase::getAnyGeneric() { return getCanonicalType().getAnyGeneric(); } - - inline bool TypeBase::isBuiltinIntegerType(unsigned n) { if (auto intTy = dyn_cast(getCanonicalType())) return intTy->getWidth().isFixedWidth() diff --git a/include/swift/ClangImporter/ClangImporterRequests.h b/include/swift/ClangImporter/ClangImporterRequests.h index d6fea3d64e88c..4376b23019913 100644 --- a/include/swift/ClangImporter/ClangImporterRequests.h +++ b/include/swift/ClangImporter/ClangImporterRequests.h @@ -132,10 +132,10 @@ class CXXNamespaceMemberLookup /// The input type for a record member lookup request. struct ClangRecordMemberLookupDescriptor final { - StructDecl *recordDecl; + NominalTypeDecl *recordDecl; DeclName name; - ClangRecordMemberLookupDescriptor(StructDecl *recordDecl, DeclName name) + ClangRecordMemberLookupDescriptor(NominalTypeDecl *recordDecl, DeclName name) : recordDecl(recordDecl), name(name) { assert(isa(recordDecl->getClangDecl())); } diff --git a/include/swift/SIL/BridgedSwiftObject.h b/include/swift/SIL/BridgedSwiftObject.h index 20f59767e80b4..3339553d4bb90 100644 --- a/include/swift/SIL/BridgedSwiftObject.h +++ b/include/swift/SIL/BridgedSwiftObject.h @@ -27,10 +27,9 @@ // Provide macros to temporarily suppress warning about the use of // _Nullable and _Nonnull. # define SWIFT_BEGIN_NULLABILITY_ANNOTATIONS \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wnullability-extension\"") + _Pragma("clang assume_nonnull begin") # define SWIFT_END_NULLABILITY_ANNOTATIONS \ - _Pragma("clang diagnostic pop") + _Pragma("clang assume_nonnull end") #else // #define _Nullable and _Nonnull to nothing if we're not being built diff --git a/include/swift/SIL/SILArgument.h b/include/swift/SIL/SILArgument.h index d05d067f66444..4f3285a2f3e88 100644 --- a/include/swift/SIL/SILArgument.h +++ b/include/swift/SIL/SILArgument.h @@ -62,7 +62,8 @@ struct SILArgumentKind { } }; -class SILArgument : public ValueBase { +class __attribute__((swift_attr("import_as_ref"))) SILArgument + : public ValueBase { friend class SILBasicBlock; SILBasicBlock *parentBlock; @@ -202,7 +203,8 @@ inline SILArgument *castToArgument(SwiftObject argument) { return static_cast(argument); } -class SILPhiArgument : public SILArgument { +class __attribute__((swift_attr("import_as_ref"))) SILPhiArgument + : public SILArgument { friend class SILBasicBlock; SILPhiArgument(SILBasicBlock *parentBlock, SILType type, @@ -310,7 +312,8 @@ class SILPhiArgument : public SILArgument { } }; -class SILFunctionArgument : public SILArgument { +class __attribute__((swift_attr("import_as_ref"))) SILFunctionArgument + : public SILArgument { friend class SILBasicBlock; bool noImplicitCopy = false; diff --git a/include/swift/SIL/SILBasicBlock.h b/include/swift/SIL/SILBasicBlock.h index f258a1455ef5d..95f2218f678db 100644 --- a/include/swift/SIL/SILBasicBlock.h +++ b/include/swift/SIL/SILBasicBlock.h @@ -31,7 +31,7 @@ class SILFunction; class SILArgument; class SILPrintContext; -class SILBasicBlock : +class __attribute__((swift_attr("import_as_ref"))) SILBasicBlock : public llvm::ilist_node, public SILAllocated, public SwiftObjectHeader { friend class SILSuccessor; diff --git a/include/swift/SIL/SILBridging.h b/include/swift/SIL/SILBridging.h index b2353ce78f206..5db337a7361fa 100644 --- a/include/swift/SIL/SILBridging.h +++ b/include/swift/SIL/SILBridging.h @@ -14,11 +14,87 @@ #define SWIFT_SIL_SILBRIDGING_H #include "BridgedSwiftObject.h" + +#include "swift/SIL/SILNode.h" +#include "swift/SIL/SILType.h" +#include "swift/SIL/SILUndef.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILBasicBlock.h" +#include "swift/SIL/SILFunction.h" + +#include "swift/AST/AnyFunctionRef.h" + #include #include +using namespace swift; + +#define INST(ID, NAME) \ +inline SILInstruction * _Nonnull getAsSILInstruction(ID * _Nonnull I) { \ + return static_cast(I); \ +} \ +inline ID * _Nullable getAs##ID(SILInstruction * _Nonnull p) { \ + return dyn_cast(p); \ +} \ +inline bool isa##ID(SILInstruction * _Nonnull p) { return isa(p); } + +#define ABSTRACT_INST(ID, NAME) \ +inline SILInstruction * _Nonnull getAsSILInstruction(ID * _Nonnull I) { \ + return static_cast(I); \ +} \ +inline ID * _Nullable getAs##ID(SILInstruction * _Nonnull p) { \ + return dyn_cast(p); \ +} \ +inline bool isa##ID(SILInstruction * _Nonnull p) { return isa(p); } + +#include "swift/SIL/SILNodes.def" +#undef INST + +#define VALUE(ID, NAME) \ +inline ID * _Nullable getAs##ID(ValueBase *v) { \ + return dyn_cast(v); \ +} \ +inline bool isa##ID(ValueBase *v) { return isa(v); } \ +inline ValueBase * _Nullable getAsValue(ID * _Nonnull v) { \ + return dyn_cast(v); \ +} + +#include "swift/SIL/SILNodes.def" +#undef SINGLE_VALUE_INST + +// There are a couple of holes in the above set of functions. +inline SILArgument * _Nullable getAsSILArgument(ValueBase *a) { + return dyn_cast(a); +} + +inline SILArgument * _Nullable getAsSILArgument(SILPhiArgument *a) { + return dyn_cast(a); +} + +inline SILArgument * _Nullable getAsSILArgument(SILFunctionArgument *a) { + return dyn_cast(a); +} + +inline SingleValueInstruction * _Nullable +getAsSingleValueInstruction(ValueBase *v) { + return dyn_cast(v); +} + +inline ValueBase * _Nullable getAsValue(SILArgument * _Nonnull v) { + return dyn_cast(v); +} + +inline ValueBase * _Nullable getAsValue(SingleValueInstruction * _Nonnull v) { + return dyn_cast(v); +} + +inline ValueBase * _Nullable getAsValue(SILValue v) { return v; } + SWIFT_BEGIN_NULLABILITY_ANNOTATIONS +template using OptionalRef = T * _Nullable; + typedef struct { const unsigned char * _Nullable data; size_t length; @@ -62,10 +138,6 @@ typedef struct { void * _Null_unspecified word2; } BridgedLocation; -typedef struct { - void * _Nullable typePtr; -} BridgedType; - typedef struct { const void * _Nullable data; size_t count; @@ -87,46 +159,10 @@ typedef struct { const void * _Nullable succ; } OptionalBridgedSuccessor; -typedef struct { - SwiftObject obj; -} BridgedFunction; - typedef struct { SwiftObject obj; } BridgedGlobalVar; -typedef struct { - SwiftObject obj; -} BridgedBasicBlock; - -typedef struct { - OptionalSwiftObject obj; -} OptionalBridgedBasicBlock; - -typedef struct { - SwiftObject obj; -} BridgedArgument; - -typedef struct { - OptionalSwiftObject obj; -} OptionalBridgedArgument; - -typedef struct { - SwiftObject obj; -} BridgedNode; - -typedef struct { - SwiftObject obj; -} BridgedValue; - -typedef struct { - SwiftObject obj; -} BridgedInstruction; - -typedef struct { - OptionalSwiftObject obj; -} OptionalBridgedInstruction; - typedef struct { SwiftObject obj; } BridgedMultiValueResult; @@ -144,6 +180,12 @@ typedef enum { typedef intptr_t SwiftInt; +// TODO: we can remove these once we auto generate equality operators for +// foreign reference types. +inline bool isPtrEq(ValueBase *a, ValueBase *b) { return a == b; } +inline bool isPtrEq(SILInstruction *a, SILInstruction *b) { return a == b; } +inline bool isPtrEq(SILBasicBlock *a, SILBasicBlock *b) { return a == b; } + void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype); void OStream_write(BridgedOStream os, BridgedStringRef str); @@ -153,90 +195,94 @@ void freeBridgedStringRef(BridgedStringRef str); void PassContext_notifyChanges(BridgedPassContext passContext, enum ChangeNotificationKind changeKind); void PassContext_eraseInstruction(BridgedPassContext passContext, - BridgedInstruction inst); + SILInstruction *inst); BridgedSlab PassContext_getNextSlab(BridgedSlab slab); BridgedSlab PassContext_allocSlab(BridgedPassContext passContext, BridgedSlab afterSlab); BridgedSlab PassContext_freeSlab(BridgedPassContext passContext, BridgedSlab slab); -BridgedStringRef SILFunction_getName(BridgedFunction function); -std::string SILFunction_debugDescription(BridgedFunction function); -OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function); -OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function); -SwiftInt SILFunction_numIndirectResultArguments(BridgedFunction function); -SwiftInt SILFunction_getSelfArgumentIndex(BridgedFunction function); +BridgedStringRef SILFunction_getName(SILFunction *function); +std::string SILFunction_debugDescription(SILFunction *function); +SILBasicBlock * _Nullable SILFunction_firstBlock(SILFunction *function); +OptionalRef SILFunction_lastBlock(SILFunction *function); +SwiftInt SILFunction_numIndirectResultArguments(SILFunction *function); +SwiftInt SILFunction_getSelfArgumentIndex(SILFunction *function); BridgedStringRef SILGlobalVariable_getName(BridgedGlobalVar global); std::string SILGlobalVariable_debugDescription(BridgedGlobalVar global); -OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block); -OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block); -BridgedFunction SILBasicBlock_getFunction(BridgedBasicBlock block); -std::string SILBasicBlock_debugDescription(BridgedBasicBlock block); -OptionalBridgedInstruction SILBasicBlock_firstInst(BridgedBasicBlock block); -OptionalBridgedInstruction SILBasicBlock_lastInst(BridgedBasicBlock block); -SwiftInt SILBasicBlock_getNumArguments(BridgedBasicBlock block); -BridgedArgument SILBasicBlock_getArgument(BridgedBasicBlock block, SwiftInt index); -OptionalBridgedSuccessor SILBasicBlock_getFirstPred(BridgedBasicBlock block); +int SILBasicBlock_mytest(SILBasicBlock *b); + +OptionalRef SILBasicBlock_next(SILBasicBlock *block); +OptionalRef SILBasicBlock_previous(SILBasicBlock *block); +SILFunction *SILBasicBlock_getFunction(SILBasicBlock *block); +std::string SILBasicBlock_debugDescription(SILBasicBlock *block); +SILInstruction *SILBasicBlock_firstInst(SILBasicBlock *block); +// TODO: we could make this a terminator inst. +OptionalRef SILBasicBlock_lastInst(SILBasicBlock *block); +SwiftInt SILBasicBlock_getNumArguments(SILBasicBlock *block); +SILArgument *SILBasicBlock_getArgument(SILBasicBlock *block, SwiftInt index); +OptionalBridgedSuccessor SILBasicBlock_getFirstPred(SILBasicBlock *block); OptionalBridgedSuccessor SILSuccessor_getNext(BridgedSuccessor succ); -BridgedBasicBlock SILSuccessor_getTargetBlock(BridgedSuccessor succ); -BridgedInstruction SILSuccessor_getContainingInst(BridgedSuccessor succ); +SILBasicBlock *SILSuccessor_getTargetBlock(BridgedSuccessor succ); +SILInstruction *SILSuccessor_getContainingInst(BridgedSuccessor succ); -BridgedValue Operand_getValue(BridgedOperand); +ValueBase *Operand_getValue(BridgedOperand); OptionalBridgedOperand Operand_nextUse(BridgedOperand); -BridgedInstruction Operand_getUser(BridgedOperand); +SILInstruction *Operand_getUser(BridgedOperand); SwiftInt Operand_isTypeDependent(BridgedOperand); -std::string SILNode_debugDescription(BridgedNode node); -OptionalBridgedOperand SILValue_firstUse(BridgedValue value); -BridgedType SILValue_getType(BridgedValue value); +std::string SILNode_debugDescription(ValueBase *node); +std::string SILInstruction_debugDescription(SILInstruction *i); +OptionalBridgedOperand SILValue_firstUse(ValueBase *value); +SILType SILValue_getType(ValueBase *value); -SwiftInt SILType_isAddress(BridgedType); -SwiftInt SILType_isTrivial(BridgedType, BridgedFunction); +SwiftInt SILType_isAddress(SILType); +SwiftInt SILType_isTrivial(SILType, SILFunction *); -BridgedBasicBlock SILArgument_getParent(BridgedArgument argument); +SILBasicBlock *SILArgument_getParent(SILArgument *argument); -OptionalBridgedInstruction SILInstruction_next(BridgedInstruction inst); -OptionalBridgedInstruction SILInstruction_previous(BridgedInstruction inst); -BridgedBasicBlock SILInstruction_getParent(BridgedInstruction inst); -BridgedArrayRef SILInstruction_getOperands(BridgedInstruction inst); -void SILInstruction_setOperand(BridgedInstruction inst, SwiftInt index, - BridgedValue value); -BridgedLocation SILInstruction_getLocation(BridgedInstruction inst); -BridgedMemoryBehavior SILInstruction_getMemBehavior(BridgedInstruction inst); +OptionalRef SILInstruction_next(SILInstruction *inst); +OptionalRef SILInstruction_previous(SILInstruction *inst); +SILBasicBlock *SILInstruction_getParent(SILInstruction *inst); +BridgedArrayRef SILInstruction_getOperands(SILInstruction *inst); +void SILInstruction_setOperand(SILInstruction *inst, SwiftInt index, + ValueBase *value); +BridgedLocation SILInstruction_getLocation(SILInstruction *inst); +BridgedMemoryBehavior SILInstruction_getMemBehavior(SILInstruction *inst); -BridgedInstruction MultiValueInstResult_getParent(BridgedMultiValueResult result); -SwiftInt MultipleValueInstruction_getNumResults(BridgedInstruction inst); +SILInstruction *MultiValueInstResult_getParent(BridgedMultiValueResult result); +SwiftInt MultipleValueInstruction_getNumResults(MultipleValueInstruction *inst); BridgedMultiValueResult - MultipleValueInstruction_getResult(BridgedInstruction inst, SwiftInt index); - -BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term); - -BridgedStringRef CondFailInst_getMessage(BridgedInstruction cfi); -BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst); -SwiftInt TupleExtractInst_fieldIndex(BridgedInstruction tei); -SwiftInt TupleElementAddrInst_fieldIndex(BridgedInstruction teai); -SwiftInt StructExtractInst_fieldIndex(BridgedInstruction sei); -SwiftInt StructElementAddrInst_fieldIndex(BridgedInstruction seai); -SwiftInt EnumInst_caseIndex(BridgedInstruction ei); -SwiftInt UncheckedEnumDataInst_caseIndex(BridgedInstruction uedi); -SwiftInt RefElementAddrInst_fieldIndex(BridgedInstruction reai); -SwiftInt PartialApplyInst_numArguments(BridgedInstruction ai); -SwiftInt ApplyInst_numArguments(BridgedInstruction ai); -SwiftInt BeginApplyInst_numArguments(BridgedInstruction ai); -SwiftInt TryApplyInst_numArguments(BridgedInstruction ai); -BridgedBasicBlock BranchInst_getTargetBlock(BridgedInstruction bi); -SwiftInt SwitchEnumInst_getNumCases(BridgedInstruction se); -SwiftInt SwitchEnumInst_getCaseIndex(BridgedInstruction se, SwiftInt idx); -SwiftInt StoreInst_getStoreOwnership(BridgedInstruction store); - -BridgedInstruction SILBuilder_createBuiltinBinaryFunction( - BridgedInstruction insertionPoint, + MultipleValueInstruction_getResult(MultipleValueInstruction *inst, SwiftInt index); + +BridgedArrayRef TermInst_getSuccessors(TermInst *term); + +BridgedStringRef CondFailInst_getMessage(CondFailInst *cfi); +BridgedGlobalVar GlobalAccessInst_getGlobal(GlobalAccessInst *globalInst); +SwiftInt TupleExtractInst_fieldIndex(TupleExtractInst *tei); +SwiftInt TupleElementAddrInst_fieldIndex(TupleElementAddrInst *teai); +SwiftInt StructExtractInst_fieldIndex(StructExtractInst *sei); +SwiftInt StructElementAddrInst_fieldIndex(StructElementAddrInst *seai); +SwiftInt EnumInst_caseIndex(EnumInst *ei); +SwiftInt UncheckedEnumDataInst_caseIndex(UncheckedEnumDataInst *uedi); +SwiftInt RefElementAddrInst_fieldIndex(RefElementAddrInst *reai); +SwiftInt PartialApplyInst_numArguments(PartialApplyInst *ai); +SwiftInt ApplyInst_numArguments(ApplyInst *ai); +SwiftInt BeginApplyInst_numArguments(BeginApplyInst *ai); +SwiftInt TryApplyInst_numArguments(TryApplyInst *ai); +SILBasicBlock *BranchInst_getTargetBlock(BranchInst *bi); +SwiftInt SwitchEnumInst_getNumCases(SwitchEnumInst *se); +SwiftInt SwitchEnumInst_getCaseIndex(SwitchEnumInst *se, SwiftInt idx); +SwiftInt StoreInst_getStoreOwnership(StoreInst *store); + +SILInstruction *SILBuilder_createBuiltinBinaryFunction( + SILInstruction *insertionPoint, BridgedLocation loc, BridgedStringRef name, - BridgedType operandType, BridgedType resultType, BridgedValueArray arguments); -BridgedInstruction SILBuilder_createCondFail(BridgedInstruction insertionPoint, - BridgedLocation loc, BridgedValue condition, BridgedStringRef messge); + SILType operandType, SILType resultType, BridgedValueArray arguments); +SILInstruction *SILBuilder_createCondFail(SILInstruction *insertionPoint, + BridgedLocation loc, ValueBase *condition, BridgedStringRef messge); SWIFT_END_NULLABILITY_ANNOTATIONS diff --git a/include/swift/SIL/SILBridgingUtils.h b/include/swift/SIL/SILBridgingUtils.h index c96dea650ec3b..9ee08416b19d6 100644 --- a/include/swift/SIL/SILBridgingUtils.h +++ b/include/swift/SIL/SILBridgingUtils.h @@ -58,34 +58,6 @@ inline const SILDebugScope *getSILDebugScope(BridgedLocation loc) { return reinterpret_cast(&loc)->getScope(); } -inline SILType getSILType(BridgedType ty) { - return SILType::getFromOpaqueValue(ty.typePtr); -} - -inline SILNode *castToSILNode(BridgedNode node) { - return static_cast(node.obj); -} - -inline SILValue castToSILValue(BridgedValue value) { - return static_cast(value.obj); -} - -inline SILType castToSILType(BridgedType type) { - return SILType::getFromOpaqueValue(type.typePtr); -} - -template I *castToInst(BridgedInstruction inst) { - return cast(static_cast(inst.obj)->castToInstruction()); -} - -inline SILBasicBlock *castToBasicBlock(BridgedBasicBlock block) { - return static_cast(block.obj); -} - -inline SILFunction *castToFunction(BridgedFunction function) { - return static_cast(function.obj); -} - inline SILGlobalVariable *castToGlobal(BridgedGlobalVar global) { return static_cast(global.obj); } diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index c2888227c87d4..22cecf0de579d 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -142,7 +142,7 @@ class SILSpecializeAttr final { /// SILFunction - A function body that has been lowered to SIL. This consists of /// zero or more SIL SILBasicBlock objects that contain the SILInstruction /// objects making up the function. -class SILFunction +class __attribute__((swift_attr("import_as_ref"))) SILFunction : public llvm::ilist_node, public SILAllocated, public SwiftObjectHeader { diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 3e2a4d68a7257..529b912c84c4a 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -317,7 +317,9 @@ SILInstructionResultArray::getReversedValues() const { /// to a SILNode without knowing which SILInstruction sub-class it is. /// Note that casting a SILInstruction to a SILNode cannot be done implicitly, /// but only with an LLVM `cast` or with SILInstruction::asSILNode(). -class SILInstruction : public llvm::ilist_node { +class __attribute__((swift_attr("import_as_ref"))) SILInstruction + : public llvm::ilist_node { + friend llvm::ilist_traits; friend llvm::ilist_traits; friend SILBasicBlock; @@ -792,7 +794,8 @@ inline SILNodePointer::SILNodePointer(const SILInstruction *inst) : /// The base class for all instructions, which are not SingleValueInstructions: /// NonValueInstruction and MultipleValueInstruction. -class NonSingleValueInstruction : public SILInstruction, public SILNode { +class __attribute__((swift_attr("import_as_ref"))) NonSingleValueInstruction +: public SILInstruction, public SILNode { friend struct SILNodeOffsetChecker; public: NonSingleValueInstruction(SILInstructionKind kind, SILDebugLocation loc) @@ -959,7 +962,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, /// Because this instruction is both a SILInstruction and a ValueBase, /// both of which inherit from SILNode, it introduces the need for /// some care when working with SILNodes. See the comment on SILNode. -class SingleValueInstruction : public SILInstruction, public ValueBase { +class __attribute__((swift_attr("import_as_ref"))) SingleValueInstruction +: public SILInstruction, public ValueBase { friend class SILInstruction; friend struct SILNodeOffsetChecker; @@ -1100,7 +1104,8 @@ class OwnershipForwardingMixin { /// /// The ownership kind is set on construction and afterwards must be changed /// explicitly using setOwnershipKind(). -class FirstArgOwnershipForwardingSingleValueInst +class __attribute__((swift_attr("import_as_ref"))) +FirstArgOwnershipForwardingSingleValueInst : public SingleValueInstruction, public OwnershipForwardingMixin { protected: @@ -1130,7 +1135,8 @@ class FirstArgOwnershipForwardingSingleValueInst /// An ownership forwarding single value that has a preferred operand of owned /// but if its inputs are all none can have OwnershipKind::None as a result. We /// assume that we always forward from operand 0. -class OwnedFirstArgForwardingSingleValueInst +class __attribute__((swift_attr("import_as_ref"))) +OwnedFirstArgForwardingSingleValueInst : public FirstArgOwnershipForwardingSingleValueInst { protected: OwnedFirstArgForwardingSingleValueInst(SILInstructionKind kind, @@ -1169,7 +1175,8 @@ class OwnedFirstArgForwardingSingleValueInst /// An instruction that forwards guaranteed or none ownership. Assumed to always /// forward from Operand(0) -> Result(0). -class GuaranteedFirstArgForwardingSingleValueInst +class __attribute__((swift_attr("import_as_ref"))) +GuaranteedFirstArgForwardingSingleValueInst : public FirstArgOwnershipForwardingSingleValueInst { protected: GuaranteedFirstArgForwardingSingleValueInst( @@ -1232,7 +1239,8 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) { } } -class AllArgOwnershipForwardingSingleValueInst +class __attribute__((swift_attr("import_as_ref"))) +AllArgOwnershipForwardingSingleValueInst : public SingleValueInstruction, public OwnershipForwardingMixin { protected: @@ -1273,7 +1281,8 @@ class AllArgOwnershipForwardingSingleValueInst /// /// *NOTE* We want this to be a pure abstract class that does not add /any/ size /// to subclasses. -class MultipleValueInstructionResult : public ValueBase { +class __attribute__((swift_attr("import_as_ref"))) +MultipleValueInstructionResult : public ValueBase { /// Return the parent instruction of this result. MultipleValueInstruction *getParentImpl() const; @@ -1352,7 +1361,8 @@ SILInstructionResultArray::SILInstructionResultArray(ArrayRef results) } /// An instruction that may produce an arbitrary number of values. -class MultipleValueInstruction : public NonSingleValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) MultipleValueInstruction +: public NonSingleValueInstruction { friend class SILInstruction; friend class SILInstructionResultArray; @@ -1499,7 +1509,8 @@ class MultipleValueInstructionTrailingObjects { @@ -2211,7 +2224,7 @@ class AllocBoxInst final /// pointer, which has the existential type. The second return value /// is an address pointing to the contained element. The contained /// value is uninitialized. -class AllocExistentialBoxInst final +class __attribute__((swift_attr("import_as_ref"))) AllocExistentialBoxInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::AllocExistentialBoxInst, AllocExistentialBoxInst, AllocationInst> { @@ -2704,7 +2717,7 @@ class ApplyInstBase }; /// ApplyInst - Represents the full application of a function value. -class ApplyInst final +class __attribute__((swift_attr("import_as_ref"))) ApplyInst final : public InstructionBase>, public llvm::TrailingObjects { @@ -2729,7 +2742,7 @@ class ApplyInst final /// PartialApplyInst - Represents the creation of a closure object by partial /// application of a function value. -class PartialApplyInst final +class __attribute__((swift_attr("import_as_ref"))) PartialApplyInst final : public InstructionBase>, @@ -2776,7 +2789,7 @@ class AbortApplyInst; /// BeginApplyInst - Represents the beginning of the full application of /// a yield_once coroutine (up until the coroutine yields a value back). -class BeginApplyInst final +class __attribute__((swift_attr("import_as_ref"))) BeginApplyInst final : public InstructionBase>, @@ -2833,7 +2846,7 @@ class BeginApplyInst final }; /// AbortApplyInst - Unwind the full application of a yield_once coroutine. -class AbortApplyInst +class __attribute__((swift_attr("import_as_ref"))) AbortApplyInst : public UnaryInstructionBase { friend SILBuilder; @@ -2856,7 +2869,7 @@ class AbortApplyInst /// EndApplyInst - Resume the full application of a yield_once coroutine /// normally. -class EndApplyInst +class __attribute__((swift_attr("import_as_ref"))) EndApplyInst : public UnaryInstructionBase { friend SILBuilder; @@ -2882,7 +2895,8 @@ class EndApplyInst //===----------------------------------------------------------------------===// /// Abstract base class for literal instructions. -class LiteralInst : public SingleValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) LiteralInst +: public SingleValueInstruction { protected: LiteralInst(SILInstructionKind Kind, SILDebugLocation DebugLoc, SILType Ty) : SingleValueInstruction(Kind, DebugLoc, Ty) {} @@ -2944,7 +2958,8 @@ class FunctionRefBaseInst : public LiteralInst { }; /// FunctionRefInst - Represents a reference to a SIL function. -class FunctionRefInst : public FunctionRefBaseInst { +class __attribute__((swift_attr("import_as_ref"))) FunctionRefInst +: public FunctionRefBaseInst { friend SILBuilder; /// Construct a FunctionRefInst. @@ -2964,7 +2979,8 @@ class FunctionRefInst : public FunctionRefBaseInst { } }; -class DynamicFunctionRefInst : public FunctionRefBaseInst { +class __attribute__((swift_attr("import_as_ref"))) DynamicFunctionRefInst +: public FunctionRefBaseInst { friend SILBuilder; /// Construct a DynamicFunctionRefInst. @@ -2981,7 +2997,8 @@ class DynamicFunctionRefInst : public FunctionRefBaseInst { } }; -class PreviousDynamicFunctionRefInst : public FunctionRefBaseInst { +class __attribute__((swift_attr("import_as_ref"))) PreviousDynamicFunctionRefInst +: public FunctionRefBaseInst { friend SILBuilder; /// Construct a PreviousDynamicFunctionRefInst. @@ -3506,7 +3523,7 @@ class KeyPathPattern final /// in order to set up a suspension. /// The continuation must be consumed by an AwaitAsyncContinuation instruction locally, /// and must dynamically be resumed exactly once during the program's ensuing execution. -class GetAsyncContinuationInstBase +class __attribute__((swift_attr("import_as_ref"))) GetAsyncContinuationInstBase : public SingleValueInstruction { protected: @@ -3534,7 +3551,7 @@ class GetAsyncContinuationInstBase }; /// Accesses the continuation for an async task, to prepare a primitive suspend operation. -class GetAsyncContinuationInst final +class __attribute__((swift_attr("import_as_ref"))) GetAsyncContinuationInst final : public InstructionBase { @@ -3557,7 +3574,7 @@ class GetAsyncContinuationInst final /// /// This variation of the instruction additionally takes an operand for the address of the /// buffer that receives the incoming value when the continuation is resumed. -class GetAsyncContinuationAddrInst final +class __attribute__((swift_attr("import_as_ref"))) GetAsyncContinuationAddrInst final : public UnaryInstructionBase { @@ -3572,7 +3589,7 @@ class GetAsyncContinuationAddrInst final /// Begins a suspension point and enqueues the continuation to the executor /// which is bound to the operand actor. -class HopToExecutorInst +class __attribute__((swift_attr("import_as_ref"))) HopToExecutorInst : public UnaryInstructionBase { @@ -3591,7 +3608,7 @@ class HopToExecutorInst }; /// Extract the ex that the code is executing on the operand executor already. -class ExtractExecutorInst +class __attribute__((swift_attr("import_as_ref"))) ExtractExecutorInst : public UnaryInstructionBase { @@ -3606,7 +3623,7 @@ class ExtractExecutorInst }; /// Instantiates a key path object. -class KeyPathInst final +class __attribute__((swift_attr("import_as_ref"))) KeyPathInst final : public InstructionBase, private llvm::TrailingObjects { @@ -3652,7 +3669,7 @@ class KeyPathInst final /// Represents an invocation of builtin functionality provided by the code /// generator. -class BuiltinInst final +class __attribute__((swift_attr("import_as_ref"))) BuiltinInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::BuiltinInst, BuiltinInst, SingleValueInstruction> { @@ -3722,7 +3739,7 @@ class BuiltinInst final /// Initializes a SIL global variable. Only valid once, before any /// usages of the global via GlobalAddrInst. -class AllocGlobalInst +class __attribute__((swift_attr("import_as_ref"))) AllocGlobalInst : public InstructionBase { friend SILBuilder; @@ -3742,7 +3759,8 @@ class AllocGlobalInst }; /// The base class for global_addr and global_value. -class GlobalAccessInst : public LiteralInst { +class __attribute__((swift_attr("import_as_ref"))) GlobalAccessInst + : public LiteralInst { SILGlobalVariable *Global; protected: @@ -3762,7 +3780,7 @@ class GlobalAccessInst : public LiteralInst { /// Gives the address of a SIL global variable. Only valid after an /// AllocGlobalInst. -class GlobalAddrInst +class __attribute__((swift_attr("import_as_ref"))) GlobalAddrInst : public InstructionBase { friend SILBuilder; @@ -3780,7 +3798,7 @@ class GlobalAddrInst }; /// Creates a base address for offset calculations. -class BaseAddrForOffsetInst +class __attribute__((swift_attr("import_as_ref"))) BaseAddrForOffsetInst : public InstructionBase { friend SILBuilder; @@ -3797,7 +3815,7 @@ class BaseAddrForOffsetInst /// /// The referenced global variable must be a statically initialized object. /// TODO: in future we might support global variables in general. -class GlobalValueInst +class __attribute__((swift_attr("import_as_ref"))) GlobalValueInst : public InstructionBase { friend SILBuilder; @@ -3808,7 +3826,7 @@ class GlobalValueInst /// IntegerLiteralInst - Encapsulates an integer constant, as defined originally /// by an IntegerLiteralExpr. -class IntegerLiteralInst final +class __attribute__((swift_attr("import_as_ref"))) IntegerLiteralInst final : public InstructionBase, private llvm::TrailingObjects { @@ -3834,7 +3852,7 @@ class IntegerLiteralInst final /// FloatLiteralInst - Encapsulates a floating point constant, as defined /// originally by a FloatLiteralExpr. -class FloatLiteralInst final +class __attribute__((swift_attr("import_as_ref"))) FloatLiteralInst final : public InstructionBase, private llvm::TrailingObjects { @@ -3862,7 +3880,7 @@ class FloatLiteralInst final /// StringLiteralInst - Encapsulates a string constant, as defined originally by /// a StringLiteralExpr. This produces the address of the string data as a /// Builtin.RawPointer. -class StringLiteralInst final +class __attribute__((swift_attr("import_as_ref"))) StringLiteralInst final : public InstructionBase, private llvm::TrailingObjects { @@ -3921,7 +3939,7 @@ enum class LoadOwnershipQualifier { static_assert(2 == SILNode::NumLoadOwnershipQualifierBits, "Size mismatch"); /// LoadInst - Represents a load from a memory location. -class LoadInst +class __attribute__((swift_attr("import_as_ref"))) LoadInst : public UnaryInstructionBase { @@ -3958,7 +3976,7 @@ enum class StoreOwnershipQualifier { static_assert(2 == SILNode::NumStoreOwnershipQualifierBits, "Size mismatch"); /// StoreInst - Represents a store from a memory location. -class StoreInst +class __attribute__((swift_attr("import_as_ref"))) StoreInst : public InstructionBase, public CopyLikeInstruction { @@ -3990,7 +4008,7 @@ class EndBorrowInst; /// Represents a load of a borrowed value. Must be paired with an end_borrow /// instruction in its use-def list. -class LoadBorrowInst : +class __attribute__((swift_attr("import_as_ref"))) LoadBorrowInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4013,7 +4031,7 @@ inline auto LoadBorrowInst::getEndBorrows() const -> EndBorrowRange { /// Represents the begin scope of a borrowed value. Must be paired with an /// end_borrow instruction in its use-def list. -class BeginBorrowInst +class __attribute__((swift_attr("import_as_ref"))) BeginBorrowInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4059,7 +4077,7 @@ inline auto BeginBorrowInst::getEndBorrows() const -> EndBorrowRange { /// Represents a store of a borrowed value into an address. Returns the borrowed /// address. Must be paired with an end_borrow in its use-def list. -class StoreBorrowInst +class __attribute__((swift_attr("import_as_ref"))) StoreBorrowInst : public InstructionBase, public CopyLikeInstruction { @@ -4087,7 +4105,7 @@ class StoreBorrowInst /// /// 2. If %src is an address, it is undefined behavior for %src to be /// destroyed or written to. -class EndBorrowInst +class __attribute__((swift_attr("import_as_ref"))) EndBorrowInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4190,7 +4208,7 @@ class EndAccessInst; /// Begins an access scope. Must be paired with an end_access instruction /// along every path. -class BeginAccessInst +class __attribute__((swift_attr("import_as_ref"))) BeginAccessInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4267,7 +4285,7 @@ class BeginAccessInst }; /// Represents the end of an access scope. -class EndAccessInst +class __attribute__((swift_attr("import_as_ref"))) EndAccessInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4310,7 +4328,7 @@ inline auto BeginAccessInst::getEndAccesses() const -> EndAccessRange { /// /// This should only be used in materializeForSet, and eventually it should /// be removed entirely. -class BeginUnpairedAccessInst +class __attribute__((swift_attr("import_as_ref"))) BeginUnpairedAccessInst : public InstructionBase { friend class SILBuilder; @@ -4393,7 +4411,7 @@ class BeginUnpairedAccessInst }; /// Ends an unpaired access. -class EndUnpairedAccessInst +class __attribute__((swift_attr("import_as_ref"))) EndUnpairedAccessInst : public UnaryInstructionBase { friend class SILBuilder; @@ -4487,7 +4505,7 @@ class AssignInstBase /// AssignInst - Represents an abstract assignment to a memory location, which /// may either be an initialization or a store sequence. This is only valid in /// Raw SIL. -class AssignInst +class __attribute__((swift_attr("import_as_ref"))) AssignInst : public AssignInstBase { friend SILBuilder; @@ -4508,7 +4526,7 @@ class AssignInst /// AssignByWrapperInst - Represents an abstract assignment via a wrapper, /// which may either be an initialization or a store sequence. This is only /// valid in Raw SIL. -class AssignByWrapperInst +class __attribute__((swift_attr("import_as_ref"))) AssignByWrapperInst : public AssignInstBase { friend SILBuilder; @@ -4551,7 +4569,7 @@ class AssignByWrapperInst /// Indicates that a memory location is uninitialized at this point and needs to /// be initialized by the end of the function and before any escape point for /// this instruction. This is only valid in Raw SIL. -class MarkUninitializedInst +class __attribute__((swift_attr("import_as_ref"))) MarkUninitializedInst : public UnaryInstructionBase { friend SILBuilder; @@ -4624,7 +4642,7 @@ class MarkUninitializedInst /// MarkFunctionEscape - Represents the escape point of set of variables due to /// a function definition which uses the variables. This is only valid in Raw /// SIL. -class MarkFunctionEscapeInst final +class __attribute__((swift_attr("import_as_ref"))) MarkFunctionEscapeInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::MarkFunctionEscapeInst, MarkFunctionEscapeInst, NonValueInstruction> { @@ -4654,7 +4672,7 @@ class MarkFunctionEscapeInst final /// Define the start or update to a symbolic variable value (for loadable /// types). -class DebugValueInst final +class __attribute__((swift_attr("import_as_ref"))) DebugValueInst final : public UnaryInstructionBase, private SILDebugVariableSupplement, @@ -4802,7 +4820,7 @@ class StoreReferenceInstBase : public InstructionBase { /// \param lvalue The SILValue representing the address to /// use for the load. #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ -class Load##Name##Inst \ +class __attribute__((swift_attr("import_as_ref"))) Load##Name##Inst \ : public LoadReferenceInstBase { \ friend SILBuilder; \ Load##Name##Inst(SILDebugLocation loc, SILValue lvalue, IsTake_t isTake) \ @@ -4814,7 +4832,7 @@ class Load##Name##Inst \ /// This is only required for address-only scenarios; for loadable /// references, it's better to use a ref_to_##name and a store. #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ -class Store##Name##Inst \ +class __attribute__((swift_attr("import_as_ref"))) Store##Name##Inst \ : public StoreReferenceInstBase { \ friend SILBuilder; \ Store##Name##Inst(SILDebugLocation loc, SILValue src, SILValue dest, \ @@ -4828,7 +4846,7 @@ class Store##Name##Inst \ /// %1 = load %src /// store %1 to %dest /// but a copy instruction must be used for address-only types. -class CopyAddrInst +class __attribute__((swift_attr("import_as_ref"))) CopyAddrInst : public InstructionBase, public CopyLikeInstruction { @@ -4873,7 +4891,8 @@ class CopyAddrInst /// /// %token is an opaque word representing the previously bound types of this /// memory region, before binding it to a contiguous region of type $T. -class BindMemoryInst final : public InstructionBaseWithTrailingOperands< +class __attribute__((swift_attr("import_as_ref"))) BindMemoryInst final + : public InstructionBaseWithTrailingOperands< SILInstructionKind::BindMemoryInst, BindMemoryInst, SingleValueInstruction> { friend SILBuilder; @@ -4948,7 +4967,7 @@ class RebindMemoryInst final : public SingleValueInstruction { /// ConversionInst - Abstract class representing instructions that convert /// values. /// -class ConversionInst : public SingleValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) ConversionInst : public SingleValueInstruction { protected: ConversionInst(SILInstructionKind Kind, SILDebugLocation DebugLoc, SILType Ty) : SingleValueInstruction(Kind, DebugLoc, Ty) {} @@ -4967,8 +4986,9 @@ class ConversionInst : public SingleValueInstruction { /// instruction's construction. /// /// The first operand is the ownership equivalent source. -class OwnershipForwardingConversionInst : public ConversionInst, - public OwnershipForwardingMixin { +class __attribute__((swift_attr("import_as_ref"))) OwnershipForwardingConversionInst + : public ConversionInst, + public OwnershipForwardingMixin { protected: OwnershipForwardingConversionInst(SILInstructionKind kind, SILDebugLocation debugLoc, SILType ty, @@ -5008,7 +5028,7 @@ class OwnershipForwardingConversionInst : public ConversionInst, /// ConvertFunctionInst - Change the type of a function value without /// affecting how it will codegen. -class ConvertFunctionInst final +class __attribute__((swift_attr("import_as_ref"))) ConvertFunctionInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::ConvertFunctionInst, ConvertFunctionInst, OwnershipForwardingConversionInst> { @@ -5056,7 +5076,7 @@ class ConvertFunctionInst final /// ConvertEscapeToNoEscapeInst - Change the type of a escaping function value /// to a trivial function type (@noescape T -> U). -class ConvertEscapeToNoEscapeInst final +class __attribute__((swift_attr("import_as_ref"))) ConvertEscapeToNoEscapeInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::ConvertEscapeToNoEscapeInst, ConvertEscapeToNoEscapeInst, ConversionInst> { @@ -5094,7 +5114,7 @@ class ConvertEscapeToNoEscapeInst final /// ThinFunctionToPointerInst - Convert a thin function pointer to a /// Builtin.RawPointer. -class ThinFunctionToPointerInst +class __attribute__((swift_attr("import_as_ref"))) ThinFunctionToPointerInst : public UnaryInstructionBase { @@ -5107,7 +5127,7 @@ class ThinFunctionToPointerInst /// PointerToThinFunctionInst - Convert a Builtin.RawPointer to a thin /// function pointer. -class PointerToThinFunctionInst final +class __attribute__((swift_attr("import_as_ref"))) PointerToThinFunctionInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::PointerToThinFunctionInst, PointerToThinFunctionInst, @@ -5126,9 +5146,10 @@ class PointerToThinFunctionInst final }; /// UpcastInst - Perform a conversion of a class instance to a supertype. -class UpcastInst final : public UnaryInstructionWithTypeDependentOperandsBase< - SILInstructionKind::UpcastInst, UpcastInst, - OwnershipForwardingConversionInst> { +class __attribute__((swift_attr("import_as_ref"))) UpcastInst final + : public UnaryInstructionWithTypeDependentOperandsBase< + SILInstructionKind::UpcastInst, UpcastInst, + OwnershipForwardingConversionInst> { friend SILBuilder; UpcastInst(SILDebugLocation DebugLoc, SILValue Operand, @@ -5145,7 +5166,7 @@ class UpcastInst final : public UnaryInstructionWithTypeDependentOperandsBase< }; /// AddressToPointerInst - Convert a SIL address to a Builtin.RawPointer value. -class AddressToPointerInst +class __attribute__((swift_attr("import_as_ref"))) AddressToPointerInst : public UnaryInstructionBase { @@ -5156,7 +5177,7 @@ class AddressToPointerInst }; /// PointerToAddressInst - Convert a Builtin.RawPointer value to a SIL address. -class PointerToAddressInst +class __attribute__((swift_attr("import_as_ref"))) PointerToAddressInst : public UnaryInstructionBase { @@ -5198,7 +5219,7 @@ class PointerToAddressInst /// Convert a heap object reference to a different type without any runtime /// checks. -class UncheckedRefCastInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedRefCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UncheckedRefCastInst, UncheckedRefCastInst, OwnershipForwardingConversionInst> { @@ -5218,7 +5239,7 @@ class UncheckedRefCastInst final }; /// Convert a value's binary representation to a trivial type of the same size. -class UncheckedTrivialBitCastInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedTrivialBitCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UncheckedTrivialBitCastInst, UncheckedTrivialBitCastInst, @@ -5238,7 +5259,7 @@ class UncheckedTrivialBitCastInst final }; /// Bitwise copy a value into another value of the same size or smaller. -class UncheckedBitwiseCastInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedBitwiseCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UncheckedBitwiseCastInst, UncheckedBitwiseCastInst, @@ -5257,7 +5278,7 @@ class UncheckedBitwiseCastInst final }; /// Bitwise copy a value into another value of the same size. -class UncheckedValueCastInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedValueCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UncheckedValueCastInst, UncheckedValueCastInst, OwnershipForwardingConversionInst> { @@ -5278,7 +5299,7 @@ class UncheckedValueCastInst final /// Build a Builtin.BridgeObject from a heap object reference by bitwise-or-ing /// in bits from a word. -class RefToBridgeObjectInst +class __attribute__((swift_attr("import_as_ref"))) RefToBridgeObjectInst : public InstructionBase { friend SILBuilder; @@ -5298,7 +5319,7 @@ class RefToBridgeObjectInst }; /// Extract the heap object reference from a BridgeObject. -class ClassifyBridgeObjectInst +class __attribute__((swift_attr("import_as_ref"))) ClassifyBridgeObjectInst : public UnaryInstructionBase { @@ -5310,7 +5331,7 @@ class ClassifyBridgeObjectInst }; /// Extract the heap object reference from a BridgeObject. -class BridgeObjectToRefInst +class __attribute__((swift_attr("import_as_ref"))) BridgeObjectToRefInst : public UnaryInstructionBase { friend SILBuilder; @@ -5322,7 +5343,7 @@ class BridgeObjectToRefInst /// Sets the BridgeObject to a tagged pointer representation holding its /// operands -class ValueToBridgeObjectInst +class __attribute__((swift_attr("import_as_ref"))) ValueToBridgeObjectInst : public UnaryInstructionBase { friend SILBuilder; @@ -5333,7 +5354,7 @@ class ValueToBridgeObjectInst }; /// Retrieve the bit pattern of a BridgeObject. -class BridgeObjectToWordInst +class __attribute__((swift_attr("import_as_ref"))) BridgeObjectToWordInst : public UnaryInstructionBase { @@ -5345,7 +5366,7 @@ class BridgeObjectToWordInst }; /// RefToRawPointer - Convert a reference type to a Builtin.RawPointer. -class RefToRawPointerInst +class __attribute__((swift_attr("import_as_ref"))) RefToRawPointerInst : public UnaryInstructionBase { @@ -5356,7 +5377,7 @@ class RefToRawPointerInst }; /// RawPointerToRefInst - Convert a Builtin.RawPointer to a reference type. -class RawPointerToRefInst +class __attribute__((swift_attr("import_as_ref"))) RawPointerToRefInst : public UnaryInstructionBase { @@ -5369,14 +5390,14 @@ class RawPointerToRefInst /// Transparent reference storage to underlying reference type conversion. /// This does nothing at runtime; it just changes the formal type. #define LOADABLE_REF_STORAGE(Name, ...) \ -class RefTo##Name##Inst \ +class __attribute__((swift_attr("import_as_ref"))) RefTo##Name##Inst \ : public UnaryInstructionBase { \ friend SILBuilder; \ RefTo##Name##Inst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty) \ : UnaryInstructionBase(DebugLoc, Operand, Ty) {} \ }; \ -class Name##ToRefInst \ +class __attribute__((swift_attr("import_as_ref"))) Name##ToRefInst \ : public UnaryInstructionBase { \ friend SILBuilder; \ @@ -5387,7 +5408,7 @@ class Name##ToRefInst \ /// ThinToThickFunctionInst - Given a thin function reference, adds a null /// context to convert the value to a thick function type. -class ThinToThickFunctionInst final +class __attribute__((swift_attr("import_as_ref"))) ThinToThickFunctionInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::ThinToThickFunctionInst, ThinToThickFunctionInst, OwnershipForwardingConversionInst> { @@ -5417,7 +5438,7 @@ class ThinToThickFunctionInst final /// Given a thick metatype value, produces an Objective-C metatype /// value. -class ThickToObjCMetatypeInst +class __attribute__((swift_attr("import_as_ref"))) ThickToObjCMetatypeInst : public UnaryInstructionBase { @@ -5430,7 +5451,7 @@ class ThickToObjCMetatypeInst /// Given an Objective-C metatype value, produces a thick metatype /// value. -class ObjCToThickMetatypeInst +class __attribute__((swift_attr("import_as_ref"))) ObjCToThickMetatypeInst : public UnaryInstructionBase { @@ -5442,7 +5463,7 @@ class ObjCToThickMetatypeInst }; /// Given an Objective-C metatype value, convert it to an AnyObject value. -class ObjCMetatypeToObjectInst +class __attribute__((swift_attr("import_as_ref"))) ObjCMetatypeToObjectInst : public UnaryInstructionBase { @@ -5455,7 +5476,7 @@ class ObjCMetatypeToObjectInst /// Given an Objective-C existential metatype value, convert it to an AnyObject /// value. -class ObjCExistentialMetatypeToObjectInst +class __attribute__((swift_attr("import_as_ref"))) ObjCExistentialMetatypeToObjectInst : public UnaryInstructionBase { @@ -5467,7 +5488,7 @@ class ObjCExistentialMetatypeToObjectInst }; /// Return the Objective-C Protocol class instance for a protocol. -class ObjCProtocolInst +class __attribute__((swift_attr("import_as_ref"))) ObjCProtocolInst : public InstructionBase { friend SILBuilder; @@ -5486,7 +5507,7 @@ class ObjCProtocolInst /// Perform an unconditional checked cast that aborts if the cast fails. -class UnconditionalCheckedCastInst final +class __attribute__((swift_attr("import_as_ref"))) UnconditionalCheckedCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UnconditionalCheckedCastInst, UnconditionalCheckedCastInst, OwnershipForwardingConversionInst> { @@ -5517,7 +5538,8 @@ class UnconditionalCheckedCastInst final /// Perform an unconditional checked cast that aborts if the cast fails. /// The result of the checked cast is left in the destination. -class UnconditionalCheckedCastValueInst final +class __attribute__((swift_attr("import_as_ref"))) +UnconditionalCheckedCastValueInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UnconditionalCheckedCastValueInst, UnconditionalCheckedCastValueInst, ConversionInst> { @@ -5549,7 +5571,8 @@ class UnconditionalCheckedCastValueInst final }; /// StructInst - Represents a constructed loadable struct. -class StructInst final : public InstructionBaseWithTrailingOperands< +class __attribute__((swift_attr("import_as_ref"))) StructInst final + : public InstructionBaseWithTrailingOperands< SILInstructionKind::StructInst, StructInst, AllArgOwnershipForwardingSingleValueInst> { friend SILBuilder; @@ -5639,7 +5662,8 @@ class StructInst final : public InstructionBaseWithTrailingOperands< /// RefCountingInst - An abstract class of instructions which /// manipulate the reference count of their object operand. -class RefCountingInst : public NonValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) RefCountingInst + : public NonValueInstruction { public: /// The atomicity of a reference counting operation to be used. enum class Atomicity : bool { @@ -5674,7 +5698,7 @@ class RefCountingInst : public NonValueInstruction { }; /// RetainValueInst - Copies a loadable value. -class RetainValueInst +class __attribute__((swift_attr("import_as_ref"))) RetainValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5687,7 +5711,7 @@ class RetainValueInst }; /// RetainValueAddrInst - Copies a loadable value by address. -class RetainValueAddrInst +class __attribute__((swift_attr("import_as_ref"))) RetainValueAddrInst : public UnaryInstructionBase { friend SILBuilder; @@ -5700,7 +5724,7 @@ class RetainValueAddrInst }; /// ReleaseValueInst - Destroys a loadable value. -class ReleaseValueInst +class __attribute__((swift_attr("import_as_ref"))) ReleaseValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5713,7 +5737,7 @@ class ReleaseValueInst }; /// ReleaseValueInst - Destroys a loadable value by address. -class ReleaseValueAddrInst +class __attribute__((swift_attr("import_as_ref"))) ReleaseValueAddrInst : public UnaryInstructionBase { friend SILBuilder; @@ -5728,7 +5752,7 @@ class ReleaseValueAddrInst /// Copies a loadable value in an unmanaged, unbalanced way. Only meant for use /// in ownership qualified SIL. Please do not use this EVER unless you are /// implementing a part of the stdlib called Unmanaged. -class UnmanagedRetainValueInst +class __attribute__((swift_attr("import_as_ref"))) UnmanagedRetainValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5743,7 +5767,7 @@ class UnmanagedRetainValueInst /// Destroys a loadable value in an unmanaged, unbalanced way. Only meant for /// use in ownership qualified SIL. Please do not use this EVER unless you are /// implementing a part of the stdlib called Unmanaged. -class UnmanagedReleaseValueInst +class __attribute__((swift_attr("import_as_ref"))) UnmanagedReleaseValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5757,7 +5781,7 @@ class UnmanagedReleaseValueInst /// Transfers ownership of a loadable value to the current autorelease /// pool. Unmanaged, so it is ignored from an ownership balancing perspective. -class UnmanagedAutoreleaseValueInst +class __attribute__((swift_attr("import_as_ref"))) UnmanagedAutoreleaseValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5770,7 +5794,7 @@ class UnmanagedAutoreleaseValueInst }; /// Transfers ownership of a loadable value to the current autorelease pool. -class AutoreleaseValueInst +class __attribute__((swift_attr("import_as_ref"))) AutoreleaseValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -5786,7 +5810,7 @@ class AutoreleaseValueInst /// /// This is the same operation what's done by a strong_release immediately /// before it calls the deallocator of the object. -class SetDeallocatingInst +class __attribute__((swift_attr("import_as_ref"))) SetDeallocatingInst : public UnaryInstructionBase { friend SILBuilder; @@ -5802,7 +5826,8 @@ class SetDeallocatingInst /// /// This instruction can only appear at the end of a gobal variable's /// static initializer list. -class ObjectInst final : public InstructionBaseWithTrailingOperands< +class __attribute__((swift_attr("import_as_ref"))) ObjectInst final + : public InstructionBaseWithTrailingOperands< SILInstructionKind::ObjectInst, ObjectInst, FirstArgOwnershipForwardingSingleValueInst> { friend SILBuilder; @@ -5848,7 +5873,8 @@ class ObjectInst final : public InstructionBaseWithTrailingOperands< }; /// TupleInst - Represents a constructed loadable tuple. -class TupleInst final : public InstructionBaseWithTrailingOperands< +class __attribute__((swift_attr("import_as_ref"))) TupleInst final + : public InstructionBaseWithTrailingOperands< SILInstructionKind::TupleInst, TupleInst, AllArgOwnershipForwardingSingleValueInst> { friend SILBuilder; @@ -5923,7 +5949,7 @@ class TupleInst final : public InstructionBaseWithTrailingOperands< /// Represents a loadable enum constructed from one of its /// elements. -class EnumInst +class __attribute__((swift_attr("import_as_ref"))) EnumInst : public InstructionBase { friend SILBuilder; @@ -5961,7 +5987,7 @@ class EnumInst /// Unsafely project the data for an enum case out of an enum without checking /// the tag. -class UncheckedEnumDataInst +class __attribute__((swift_attr("import_as_ref"))) UncheckedEnumDataInst : public UnaryInstructionBase { friend SILBuilder; @@ -5998,7 +6024,7 @@ class UncheckedEnumDataInst /// Projects the address of the data for a case inside an uninitialized enum in /// order to initialize the payload for that case. -class InitEnumDataAddrInst +class __attribute__((swift_attr("import_as_ref"))) InitEnumDataAddrInst : public UnaryInstructionBase { @@ -6016,7 +6042,7 @@ class InitEnumDataAddrInst /// InjectEnumAddrInst - Tags an enum as containing a case. The data for /// that case, if any, must have been written into the enum first. -class InjectEnumAddrInst +class __attribute__((swift_attr("import_as_ref"))) InjectEnumAddrInst : public UnaryInstructionBase { @@ -6034,7 +6060,7 @@ class InjectEnumAddrInst /// Invalidate an enum value and take ownership of its payload data /// without moving it in memory. -class UncheckedTakeEnumDataAddrInst +class __attribute__((swift_attr("import_as_ref"))) UncheckedTakeEnumDataAddrInst : public UnaryInstructionBase { @@ -6112,7 +6138,7 @@ class SelectInstBase : public Base { /// Common base class for the select_enum and select_enum_addr instructions, /// which select one of a set of possible results based on the case of an enum. -class SelectEnumInstBase +class __attribute__((swift_attr("import_as_ref"))) SelectEnumInstBase : public SelectInstBase { // Tail-allocated after the operands is an array of `NumCases` // EnumElementDecl* pointers, referencing the case discriminators for each @@ -6191,8 +6217,9 @@ class SelectEnumInstBase }; /// A select enum inst that produces a static OwnershipKind. -class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase, - public OwnershipForwardingMixin { +class __attribute__((swift_attr("import_as_ref"))) OwnershipForwardingSelectEnumInstBase + : public SelectEnumInstBase, + public OwnershipForwardingMixin { protected: OwnershipForwardingSelectEnumInstBase( SILInstructionKind kind, SILDebugLocation debugLoc, SILType type, @@ -6224,7 +6251,7 @@ class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase, }; /// Select one of a set of values based on the case of an enum. -class SelectEnumInst final +class __attribute__((swift_attr("import_as_ref"))) SelectEnumInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::SelectEnumInst, SelectEnumInst, OwnershipForwardingSelectEnumInstBase, EnumElementDecl *> { @@ -6256,7 +6283,7 @@ class SelectEnumInst final }; /// Select one of a set of values based on the case of an enum. -class SelectEnumAddrInst final +class __attribute__((swift_attr("import_as_ref"))) SelectEnumAddrInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::SelectEnumAddrInst, SelectEnumAddrInst, SelectEnumInstBase, EnumElementDecl *> { @@ -6289,7 +6316,7 @@ class SelectEnumAddrInst final /// /// There is 'the' operand, followed by pairs of operands for each case, /// followed by an optional default operand. -class SelectValueInst final +class __attribute__((swift_attr("import_as_ref"))) SelectValueInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::SelectValueInst, SelectValueInst, SelectInstBase> { @@ -6331,7 +6358,7 @@ class SelectValueInst final /// MetatypeInst - Represents the production of an instance of a given metatype /// named statically. -class MetatypeInst final +class __attribute__((swift_attr("import_as_ref"))) MetatypeInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::MetatypeInst, MetatypeInst, SingleValueInstruction> { @@ -6357,7 +6384,7 @@ class MetatypeInst final }; /// Represents loading a dynamic metatype from a value. -class ValueMetatypeInst +class __attribute__((swift_attr("import_as_ref"))) ValueMetatypeInst : public UnaryInstructionBase { @@ -6369,7 +6396,7 @@ class ValueMetatypeInst /// ExistentialMetatype - Represents loading a dynamic metatype from an /// existential container. -class ExistentialMetatypeInst +class __attribute__((swift_attr("import_as_ref"))) ExistentialMetatypeInst : public UnaryInstructionBase { @@ -6381,7 +6408,7 @@ class ExistentialMetatypeInst }; /// Extract a numbered element out of a value of tuple type. -class TupleExtractInst +class __attribute__((swift_attr("import_as_ref"))) TupleExtractInst : public UnaryInstructionBase { friend SILBuilder; @@ -6414,7 +6441,7 @@ class TupleExtractInst }; /// Derive the address of a numbered element from the address of a tuple. -class TupleElementAddrInst +class __attribute__((swift_attr("import_as_ref"))) TupleElementAddrInst : public UnaryInstructionBase { @@ -6525,7 +6552,7 @@ class FieldIndexCacheBase : public ParentTy { }; /// Extract a physical, fragile field out of a value of struct type. -class StructExtractInst +class __attribute__((swift_attr("import_as_ref"))) StructExtractInst : public UnaryInstructionBase< SILInstructionKind::StructExtractInst, FieldIndexCacheBase> { @@ -6553,7 +6580,7 @@ class StructExtractInst }; /// Derive the address of a physical field from the address of a struct. -class StructElementAddrInst +class __attribute__((swift_attr("import_as_ref"))) StructElementAddrInst : public UnaryInstructionBase> { friend SILBuilder; @@ -6570,7 +6597,7 @@ class StructElementAddrInst /// RefElementAddrInst - Derive the address of a named element in a reference /// type instance. -class RefElementAddrInst +class __attribute__((swift_attr("import_as_ref"))) RefElementAddrInst : public UnaryInstructionBase> { friend SILBuilder; @@ -6598,7 +6625,7 @@ class RefElementAddrInst /// RefTailAddrInst - Derive the address of the first element of the first /// tail-allocated array in a reference type instance. -class RefTailAddrInst +class __attribute__((swift_attr("import_as_ref"))) RefTailAddrInst : public UnaryInstructionBase { @@ -6633,7 +6660,8 @@ class RefTailAddrInst /// MethodInst - Abstract base for instructions that implement dynamic /// method lookup. -class MethodInst : public SingleValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) MethodInst + : public SingleValueInstruction { SILDeclRef Member; public: MethodInst(SILInstructionKind Kind, SILDebugLocation DebugLoc, SILType Ty, @@ -6649,7 +6677,7 @@ class MethodInst : public SingleValueInstruction { /// ClassMethodInst - Given the address of a value of class type and a method /// constant, extracts the implementation of that method for the dynamic /// instance type of the class. -class ClassMethodInst +class __attribute__((swift_attr("import_as_ref"))) ClassMethodInst : public UnaryInstructionBase { @@ -6663,7 +6691,7 @@ class ClassMethodInst /// SuperMethodInst - Given the address of a value of class type and a method /// constant, extracts the implementation of that method for the superclass of /// the static type of the class. -class SuperMethodInst +class __attribute__((swift_attr("import_as_ref"))) SuperMethodInst : public UnaryInstructionBase { friend SILBuilder; @@ -6676,7 +6704,7 @@ class SuperMethodInst /// ObjCMethodInst - Given the address of a value of class type and a method /// constant, extracts the implementation of that method for the dynamic /// instance type of the class. -class ObjCMethodInst final +class __attribute__((swift_attr("import_as_ref"))) ObjCMethodInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::ObjCMethodInst, ObjCMethodInst, @@ -6698,7 +6726,7 @@ class ObjCMethodInst final /// ObjCSuperMethodInst - Given the address of a value of class type and a method /// constant, extracts the implementation of that method for the superclass of /// the static type of the class. -class ObjCSuperMethodInst +class __attribute__((swift_attr("import_as_ref"))) ObjCSuperMethodInst : public UnaryInstructionBase { friend SILBuilder; @@ -6711,7 +6739,7 @@ class ObjCSuperMethodInst /// WitnessMethodInst - Given a type, a protocol conformance, /// and a protocol method constant, extracts the implementation of that method /// for the type. -class WitnessMethodInst final +class __attribute__((swift_attr("import_as_ref"))) WitnessMethodInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::WitnessMethodInst, WitnessMethodInst, MethodInst> { @@ -6771,7 +6799,7 @@ OpenedExistentialAccess getOpenedExistentialAccessFor(AccessKind access); /// Given the address of an existential, "opens" the /// existential by returning a pointer to a fresh archetype T, which also /// captures the (dynamic) conformances. -class OpenExistentialAddrInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialAddrInst : public UnaryInstructionBase { @@ -6788,7 +6816,7 @@ class OpenExistentialAddrInst /// Given an opaque value referring to an existential, "opens" the /// existential by returning a pointer to a fresh archetype T, which also /// captures the (dynamic) conformances. -class OpenExistentialValueInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -6801,7 +6829,7 @@ class OpenExistentialValueInst /// Given a class existential, "opens" the /// existential by returning a pointer to a fresh archetype T, which also /// captures the (dynamic) conformances. -class OpenExistentialRefInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialRefInst : public UnaryInstructionBase { friend SILBuilder; @@ -6815,7 +6843,7 @@ class OpenExistentialRefInst /// "opens" the existential by returning a pointer to a fresh /// archetype metatype T.Type, which also captures the (dynamic) /// conformances. -class OpenExistentialMetatypeInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialMetatypeInst : public UnaryInstructionBase { @@ -6828,7 +6856,7 @@ class OpenExistentialMetatypeInst /// Given a boxed existential container, /// "opens" the existential by returning a pointer to a fresh /// archetype T, which also captures the (dynamic) conformances. -class OpenExistentialBoxInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialBoxInst : public UnaryInstructionBase { @@ -6840,7 +6868,7 @@ class OpenExistentialBoxInst /// Given a boxed existential container, "opens" the existential by returning a /// fresh archetype T, which also captures the (dynamic) conformances. -class OpenExistentialBoxValueInst +class __attribute__((swift_attr("import_as_ref"))) OpenExistentialBoxValueInst : public UnaryInstructionBase< SILInstructionKind::OpenExistentialBoxValueInst, GuaranteedFirstArgForwardingSingleValueInst> { @@ -6855,7 +6883,7 @@ class OpenExistentialBoxValueInst /// a protocol type, initializes its existential container to contain a concrete /// value of the given type, and returns the address of the uninitialized /// concrete value inside the existential container. -class InitExistentialAddrInst final +class __attribute__((swift_attr("import_as_ref"))) InitExistentialAddrInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::InitExistentialAddrInst, InitExistentialAddrInst, @@ -6898,7 +6926,7 @@ class InitExistentialAddrInst final /// initializes its existential container to contain a concrete /// value of the given type, and returns the uninitialized /// concrete value inside the existential container. -class InitExistentialValueInst final +class __attribute__((swift_attr("import_as_ref"))) InitExistentialValueInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::InitExistentialValueInst, InitExistentialValueInst, SingleValueInstruction> { @@ -6931,7 +6959,7 @@ class InitExistentialValueInst final /// InitExistentialRefInst - Given a class instance reference and a set of /// conformances, creates a class existential value referencing the /// class instance. -class InitExistentialRefInst final +class __attribute__((swift_attr("import_as_ref"))) InitExistentialRefInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::InitExistentialRefInst, InitExistentialRefInst, FirstArgOwnershipForwardingSingleValueInst> { @@ -6969,7 +6997,7 @@ class InitExistentialRefInst final /// InitExistentialMetatypeInst - Given a metatype reference and a set /// of conformances, creates an existential metatype value referencing /// the metatype. -class InitExistentialMetatypeInst final +class __attribute__((swift_attr("import_as_ref"))) InitExistentialMetatypeInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::InitExistentialMetatypeInst, InitExistentialMetatypeInst, @@ -7015,7 +7043,7 @@ class InitExistentialMetatypeInst final /// the value buffer. This should only be used for partially-initialized /// existentials; a fully-initialized existential can be destroyed with /// DestroyAddrInst and deallocated with DeallocStackInst. -class DeinitExistentialAddrInst +class __attribute__((swift_attr("import_as_ref"))) DeinitExistentialAddrInst : public UnaryInstructionBase { @@ -7025,7 +7053,7 @@ class DeinitExistentialAddrInst : UnaryInstructionBase(DebugLoc, Existential) {} }; -class DeinitExistentialValueInst +class __attribute__((swift_attr("import_as_ref"))) DeinitExistentialValueInst : public UnaryInstructionBase { friend SILBuilder; @@ -7035,7 +7063,7 @@ class DeinitExistentialValueInst }; /// Projects the capture storage address from a @block_storage address. -class ProjectBlockStorageInst +class __attribute__((swift_attr("import_as_ref"))) ProjectBlockStorageInst : public UnaryInstructionBase { @@ -7049,7 +7077,7 @@ class ProjectBlockStorageInst /// Initializes a block header, creating a block that /// invokes a given thin cdecl function. -class InitBlockStorageHeaderInst +class __attribute__((swift_attr("import_as_ref"))) InitBlockStorageHeaderInst : public InstructionBase { friend SILBuilder; @@ -7083,7 +7111,7 @@ class InitBlockStorageHeaderInst }; /// StrongRetainInst - Increase the strong reference count of an object. -class StrongRetainInst +class __attribute__((swift_attr("import_as_ref"))) StrongRetainInst : public UnaryInstructionBase { @@ -7101,7 +7129,7 @@ class StrongRetainInst /// An object can be destroyed when its strong reference count is /// zero. It can be deallocated when both its strong reference and /// weak reference counts reach zero. -class StrongReleaseInst +class __attribute__((swift_attr("import_as_ref"))) StrongReleaseInst : public UnaryInstructionBase { @@ -7124,7 +7152,7 @@ class StrongReleaseInst /// /// Name##ReleaseInst - Decrease the 'name' reference count of an object. #define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ -class StrongRetain##Name##Inst \ +class __attribute__((swift_attr("import_as_ref"))) StrongRetain##Name##Inst \ : public UnaryInstructionBase { \ friend SILBuilder; \ @@ -7134,7 +7162,7 @@ class StrongRetain##Name##Inst \ setAtomicity(atomicity); \ } \ }; \ -class Name##RetainInst \ +class __attribute__((swift_attr("import_as_ref"))) Name##RetainInst \ : public UnaryInstructionBase { \ friend SILBuilder; \ @@ -7144,7 +7172,7 @@ class Name##RetainInst \ setAtomicity(atomicity); \ } \ }; \ -class Name##ReleaseInst \ +class __attribute__((swift_attr("import_as_ref"))) Name##ReleaseInst \ : public UnaryInstructionBase { \ friend SILBuilder; \ @@ -7158,7 +7186,7 @@ class Name##ReleaseInst \ /// FixLifetimeInst - An artificial use of a value for the purposes of ARC or /// RVO optimizations. -class FixLifetimeInst : +class __attribute__((swift_attr("import_as_ref"))) FixLifetimeInst : public UnaryInstructionBase { @@ -7181,7 +7209,7 @@ class FixLifetimeInst : /// lifetime ending use allowing for static verification of deallocating /// destroyers, without an actual release being emitted (avoiding the runtime /// assert). -class EndLifetimeInst +class __attribute__((swift_attr("import_as_ref"))) EndLifetimeInst : public UnaryInstructionBase { friend SILBuilder; @@ -7195,7 +7223,7 @@ class EndLifetimeInst /// This is used today in destructors where due to Objective-C legacy /// constraints, we need to be able to convert a guaranteed parameter to an owned /// parameter. -class UncheckedOwnershipConversionInst +class __attribute__((swift_attr("import_as_ref"))) UncheckedOwnershipConversionInst : public UnaryInstructionBase { friend SILBuilder; @@ -7237,7 +7265,7 @@ class UncheckedOwnershipConversionInst /// result) have a dependence on "base" being alive. Do not allow for things /// that /may/ destroy base to be moved earlier than any of these uses of /// "value"'. -class MarkDependenceInst +class __attribute__((swift_attr("import_as_ref"))) MarkDependenceInst : public InstructionBase { friend SILBuilder; @@ -7269,7 +7297,7 @@ class MarkDependenceInst /// Promote an Objective-C block that is on the stack to the heap, or simply /// retain a block that is already on the heap. -class CopyBlockInst +class __attribute__((swift_attr("import_as_ref"))) CopyBlockInst : public UnaryInstructionBase { @@ -7279,7 +7307,7 @@ class CopyBlockInst : UnaryInstructionBase(DebugLoc, operand, operand->getType()) {} }; -class CopyBlockWithoutEscapingInst +class __attribute__((swift_attr("import_as_ref"))) CopyBlockWithoutEscapingInst : public InstructionBase { friend SILBuilder; @@ -7308,7 +7336,7 @@ class CopyBlockWithoutEscapingInst MutableArrayRef getAllOperands() { return Operands.asArray(); } }; -class CopyValueInst +class __attribute__((swift_attr("import_as_ref"))) CopyValueInst : public UnaryInstructionBase { friend class SILBuilder; @@ -7327,7 +7355,7 @@ class ExplicitCopyValueInst }; #define UNCHECKED_REF_STORAGE(Name, ...) \ - class StrongCopy##Name##ValueInst \ + class __attribute__((swift_attr("import_as_ref"))) StrongCopy##Name##ValueInst \ : public UnaryInstructionBase< \ SILInstructionKind::StrongCopy##Name##ValueInst, \ SingleValueInstruction> { \ @@ -7338,7 +7366,7 @@ class ExplicitCopyValueInst }; #define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ - class StrongCopy##Name##ValueInst \ + class __attribute__((swift_attr("import_as_ref"))) StrongCopy##Name##ValueInst \ : public UnaryInstructionBase< \ SILInstructionKind::StrongCopy##Name##ValueInst, \ SingleValueInstruction> { \ @@ -7349,7 +7377,7 @@ class ExplicitCopyValueInst }; #include "swift/AST/ReferenceStorage.def" -class DestroyValueInst +class __attribute__((swift_attr("import_as_ref"))) DestroyValueInst : public UnaryInstructionBase { friend class SILBuilder; @@ -7375,7 +7403,7 @@ class DestroyValueInst } }; -class MoveValueInst +class __attribute__((swift_attr("import_as_ref"))) MoveValueInst : public UnaryInstructionBase { friend class SILBuilder; @@ -7395,7 +7423,7 @@ class MoveValueInst /// Given an object reference, return true iff it is non-nil and refers /// to a native swift object with strong reference count of 1. -class IsUniqueInst +class __attribute__((swift_attr("import_as_ref"))) IsUniqueInst : public UnaryInstructionBase { @@ -7411,7 +7439,7 @@ class IsUniqueInst /// Returns two results: the first result is an Int1 which is the result of the /// uniqueness check. The second result is the class reference operand, which /// can be used for mutation. -class BeginCOWMutationInst final +class __attribute__((swift_attr("import_as_ref"))) BeginCOWMutationInst final : public UnaryInstructionBase, public MultipleValueInstructionTrailingObjects @@ -7451,7 +7479,7 @@ class BeginCOWMutationInst final }; /// Marks the end of the mutation of a reference counted object. -class EndCOWMutationInst +class __attribute__((swift_attr("import_as_ref"))) EndCOWMutationInst : public UnaryInstructionBase { @@ -7475,7 +7503,7 @@ class EndCOWMutationInst /// Given an escaping closure return true iff it has a non-nil context and the /// context has a strong reference count greater than 1. -class IsEscapingClosureInst +class __attribute__((swift_attr("import_as_ref"))) IsEscapingClosureInst : public UnaryInstructionBase { friend SILBuilder; @@ -7498,7 +7526,8 @@ class IsEscapingClosureInst //===----------------------------------------------------------------------===// /// DeallocationInst - An abstract parent class for Dealloc{Stack, Box, Ref}. -class DeallocationInst : public NonValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) DeallocationInst + : public NonValueInstruction { protected: DeallocationInst(SILInstructionKind Kind, SILDebugLocation DebugLoc) : NonValueInstruction(Kind, DebugLoc) {} @@ -7508,7 +7537,7 @@ class DeallocationInst : public NonValueInstruction { }; /// DeallocStackInst - Deallocate stack memory allocated by alloc_stack. -class DeallocStackInst : +class __attribute__((swift_attr("import_as_ref"))) DeallocStackInst : public UnaryInstructionBase { friend SILBuilder; @@ -7525,7 +7554,7 @@ class DeallocStackInst : /// /// It is undefined behavior if the type of the operand does not match the /// most derived type of the allocated instance. -class DeallocRefInst : +class __attribute__((swift_attr("import_as_ref"))) DeallocRefInst : public UnaryInstructionBase { friend SILBuilder; @@ -7556,7 +7585,7 @@ class DeallocRefInst : /// /// The metatype value can either be the static self type (in a designated /// initializer) or a dynamic self type (in a convenience initializer). -class DeallocPartialRefInst +class __attribute__((swift_attr("import_as_ref"))) DeallocPartialRefInst : public InstructionBase { friend SILBuilder; @@ -7583,7 +7612,7 @@ class DeallocPartialRefInst /// /// This does not destroy the boxed value instance; it must either be /// uninitialized or have been manually destroyed. -class DeallocBoxInst +class __attribute__((swift_attr("import_as_ref"))) DeallocBoxInst : public UnaryInstructionBase { @@ -7599,7 +7628,7 @@ class DeallocBoxInst /// /// This does not destroy the boxed value instance; it must either be /// uninitialized or have been manually destroyed. -class DeallocExistentialBoxInst +class __attribute__((swift_attr("import_as_ref"))) DeallocExistentialBoxInst : public UnaryInstructionBase { @@ -7621,7 +7650,7 @@ class DeallocExistentialBoxInst /// release_value %1 /// but a destroy instruction can be used for types that cannot be loaded, /// such as resilient value types. -class DestroyAddrInst +class __attribute__((swift_attr("import_as_ref"))) DestroyAddrInst : public UnaryInstructionBase { @@ -7632,7 +7661,7 @@ class DestroyAddrInst }; /// Project out the address of the value in a box. -class ProjectBoxInst +class __attribute__((swift_attr("import_as_ref"))) ProjectBoxInst : public UnaryInstructionBase { friend SILBuilder; @@ -7652,7 +7681,7 @@ class ProjectBoxInst }; /// Project out the address of the value in an existential box. -class ProjectExistentialBoxInst +class __attribute__((swift_attr("import_as_ref"))) ProjectExistentialBoxInst : public UnaryInstructionBase { friend SILBuilder; @@ -7670,7 +7699,7 @@ class ProjectExistentialBoxInst /// /// Optionally cond_fail has a static failure message, which is displayed in the debugger in case the failure /// is triggered. -class CondFailInst final +class __attribute__((swift_attr("import_as_ref"))) CondFailInst final : public UnaryInstructionBase, private llvm::TrailingObjects @@ -7696,7 +7725,8 @@ class CondFailInst final //===----------------------------------------------------------------------===// /// Abstract base class for indexing instructions. -class IndexingInst : public SingleValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) IndexingInst + : public SingleValueInstruction { enum { Base, Index }; FixedOperandList<2> Operands; public: @@ -7717,7 +7747,7 @@ class IndexingInst : public SingleValueInstruction { /// IndexAddrInst - "%2 : $*T = index_addr %0 : $*T, %1 : $Builtin.Word" /// This takes an address and indexes it, striding by the pointed- /// to type. This is used to index into arrays of uniform elements. -class IndexAddrInst +class __attribute__((swift_attr("import_as_ref"))) IndexAddrInst : public InstructionBase { friend SILBuilder; @@ -7730,7 +7760,7 @@ class IndexAddrInst /// TailAddrInst - like IndexingInst, but aligns-up the resulting address to a /// tail-allocated element type. -class TailAddrInst +class __attribute__((swift_attr("import_as_ref"))) TailAddrInst : public InstructionBase { friend SILBuilder; @@ -7748,7 +7778,7 @@ class TailAddrInst /// = index_raw_pointer %0 : $Builtin.RawPointer, %1 : $Builtin.Word /// This takes an address and indexes it, striding by the pointed- /// to type. This is used to index into arrays of uniform elements. -class IndexRawPointerInst +class __attribute__((swift_attr("import_as_ref"))) IndexRawPointerInst : public InstructionBase { friend SILBuilder; @@ -7772,7 +7802,8 @@ enum class TermKind { }; /// This class defines a "terminating instruction" for a SILBasicBlock. -class TermInst : public NonValueInstruction { +class __attribute__((swift_attr("import_as_ref"))) TermInst + : public NonValueInstruction { protected: TermInst(SILInstructionKind K, SILDebugLocation DebugLoc) : NonValueInstruction(K, DebugLoc) {} @@ -7922,8 +7953,8 @@ class TermInst : public NonValueInstruction { }; // Forwards the first operand to a result in each successor block. -class OwnershipForwardingTermInst : public TermInst, - public OwnershipForwardingMixin { +class __attribute__((swift_attr("import_as_ref"))) OwnershipForwardingTermInst + : public TermInst, public OwnershipForwardingMixin { protected: OwnershipForwardingTermInst(SILInstructionKind kind, SILDebugLocation debugLoc, @@ -7958,7 +7989,7 @@ class OwnershipForwardingTermInst : public TermInst, /// UnreachableInst - Position in the code which would be undefined to reach. /// These are always implicitly generated, e.g. when falling off the end of a /// function or after a no-return function call. -class UnreachableInst +class __attribute__((swift_attr("import_as_ref"))) UnreachableInst : public InstructionBase { friend SILBuilder; @@ -7977,7 +8008,7 @@ class UnreachableInst }; /// ReturnInst - Representation of a ReturnStmt. -class ReturnInst +class __attribute__((swift_attr("import_as_ref"))) ReturnInst : public UnaryInstructionBase { friend SILBuilder; @@ -8009,7 +8040,7 @@ class ReturnInst /// ThrowInst - Throw a typed error (which, in our system, is /// essentially just a funny kind of return). -class ThrowInst +class __attribute__((swift_attr("import_as_ref"))) ThrowInst : public UnaryInstructionBase { friend SILBuilder; @@ -8032,7 +8063,7 @@ class ThrowInst /// UnwindInst - Continue unwinding out of this function. Currently this is /// only used in coroutines as the eventual terminator of the unwind edge /// out of a 'yield'. -class UnwindInst +class __attribute__((swift_attr("import_as_ref"))) UnwindInst : public InstructionBase { friend SILBuilder; @@ -8052,7 +8083,7 @@ class UnwindInst /// Suspend execution of an async task until /// essentially just a funny kind of return). -class AwaitAsyncContinuationInst final +class __attribute__((swift_attr("import_as_ref"))) AwaitAsyncContinuationInst final : public UnaryInstructionBase { @@ -8100,7 +8131,7 @@ class AwaitAsyncContinuationInst final /// /// This is a terminator because the caller can abort the coroutine, /// e.g. if an error is thrown and an unwind is provoked. -class YieldInst final +class __attribute__((swift_attr("import_as_ref"))) YieldInst final : public InstructionBaseWithTrailingOperands { friend SILBuilder; @@ -8156,7 +8187,7 @@ class YieldInst final }; /// BranchInst - An unconditional branch. -class BranchInst final +class __attribute__((swift_attr("import_as_ref"))) BranchInst final : public InstructionBaseWithTrailingOperands { friend SILBuilder; @@ -8207,7 +8238,7 @@ class BranchInst final }; /// A conditional branch. -class CondBranchInst final +class __attribute__((swift_attr("import_as_ref"))) CondBranchInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::CondBranchInst, CondBranchInst, @@ -8387,7 +8418,7 @@ class CondBranchInst final }; /// A switch on a value of a builtin type. -class SwitchValueInst final +class __attribute__((swift_attr("import_as_ref"))) SwitchValueInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::SwitchValueInst, SwitchValueInst, TermInst, SILSuccessor> { @@ -8671,7 +8702,7 @@ class SwitchEnumInstBase : public BaseTy { /// A switch on a loadable enum's discriminator. The data for each case is /// passed into the corresponding destination block as an argument. -class SwitchEnumInst +class __attribute__((swift_attr("import_as_ref"))) SwitchEnumInst : public InstructionBase> { friend SILBuilder; @@ -8702,7 +8733,7 @@ class SwitchEnumInst SILPhiArgument *createOptionalSomeResult(); }; /// A switch on an enum's discriminator in memory. -class SwitchEnumAddrInst +class __attribute__((swift_attr("import_as_ref"))) SwitchEnumAddrInst : public InstructionBase> { friend SILBuilder; @@ -8729,7 +8760,7 @@ class SwitchEnumAddrInst /// /// If the method exists, branches to the first BB, providing it with the /// method reference; otherwise, branches to the second BB. -class DynamicMethodBranchInst +class __attribute__((swift_attr("import_as_ref"))) DynamicMethodBranchInst : public InstructionBase { friend SILBuilder; @@ -8802,7 +8833,8 @@ template class CastBranchInstBase : public BaseTy { /// The base class for cast instructions which are terminators and have a /// CastConsumptionKind. -class CastBranchWithConsumptionKindBase : public CastBranchInstBase { +class __attribute__((swift_attr("import_as_ref"))) +CastBranchWithConsumptionKindBase : public CastBranchInstBase { CastConsumptionKind ConsumptionKind; public: @@ -8889,7 +8921,7 @@ class AddrCastInstBase /// Perform a checked cast operation and branch on whether the cast succeeds. /// The success branch destination block receives the cast result as a BB /// argument. -class CheckedCastBranchInst final +class __attribute__((swift_attr("import_as_ref"))) CheckedCastBranchInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::CheckedCastBranchInst, CheckedCastBranchInst, CastBranchInstBase> { @@ -8933,7 +8965,7 @@ class CheckedCastBranchInst final /// Perform a checked cast operation and branch on whether the cast succeeds. /// The success branch destination block receives the cast result as a BB /// argument. -class CheckedCastValueBranchInst final +class __attribute__((swift_attr("import_as_ref"))) CheckedCastValueBranchInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::CheckedCastValueBranchInst, CheckedCastValueBranchInst, CastBranchInstBase> { @@ -8971,7 +9003,7 @@ class CheckedCastValueBranchInst final /// Perform a checked cast operation and branch on whether the cast succeeds. /// The result of the checked cast is left in the destination address. -class CheckedCastAddrBranchInst final +class __attribute__((swift_attr("import_as_ref"))) CheckedCastAddrBranchInst final : public AddrCastInstBase< SILInstructionKind::CheckedCastAddrBranchInst, CheckedCastAddrBranchInst, CastBranchWithConsumptionKindBase> { @@ -8997,7 +9029,7 @@ class CheckedCastAddrBranchInst final /// checks. This is a variant of UncheckedRefCast that works on address types, /// thus encapsulates an implicit load and take of the reference followed by a /// store and initialization of a new reference. -class UncheckedRefCastAddrInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedRefCastAddrInst final : public AddrCastInstBase< SILInstructionKind::UncheckedRefCastAddrInst, UncheckedRefCastAddrInst, NonValueInstruction> { @@ -9011,7 +9043,7 @@ class UncheckedRefCastAddrInst final SILValue dest, CanType targetType, SILFunction &F); }; -class UncheckedAddrCastInst final +class __attribute__((swift_attr("import_as_ref"))) UncheckedAddrCastInst final : public UnaryInstructionWithTypeDependentOperandsBase< SILInstructionKind::UncheckedAddrCastInst, UncheckedAddrCastInst, @@ -9030,7 +9062,8 @@ class UncheckedAddrCastInst final /// Perform an unconditional checked cast that aborts if the cast fails. /// The result of the checked cast is left in the destination address. -class UnconditionalCheckedCastAddrInst final +class __attribute__((swift_attr("import_as_ref"))) +UnconditionalCheckedCastAddrInst final : public AddrCastInstBase< SILInstructionKind::UnconditionalCheckedCastAddrInst, UnconditionalCheckedCastAddrInst, NonValueInstruction> { @@ -9048,7 +9081,8 @@ class UnconditionalCheckedCastAddrInst final }; /// A private abstract class to store the destinations of a TryApplyInst. -class TryApplyInstBase : public TermInst { +class __attribute__((swift_attr("import_as_ref"))) TryApplyInstBase + : public TermInst { public: enum { // Map branch targets to block successor indices. @@ -9084,7 +9118,7 @@ class TryApplyInstBase : public TermInst { /// TryApplyInst - Represents the full application of a function that /// can produce an error. -class TryApplyInst final +class __attribute__((swift_attr("import_as_ref"))) TryApplyInst final : public InstructionBase>, public llvm::TrailingObjects { @@ -9113,7 +9147,7 @@ class TryApplyInst final /// (optional). The differentiation transform canonicalizes /// `differentiable_function` instructions, filling in derivative function /// operands if missing. -class DifferentiableFunctionInst final +class __attribute__((swift_attr("import_as_ref"))) DifferentiableFunctionInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::DifferentiableFunctionInst, DifferentiableFunctionInst, @@ -9200,7 +9234,7 @@ class DifferentiableFunctionInst final /// LinearFunctionInst - given a function, its derivative and traspose functions, /// create an `@differentiable(_linear)` function that represents a bundle of these. -class LinearFunctionInst final +class __attribute__((swift_attr("import_as_ref"))) LinearFunctionInst final : public InstructionBaseWithTrailingOperands< SILInstructionKind::LinearFunctionInst, LinearFunctionInst, AllArgOwnershipForwardingSingleValueInst> { @@ -9240,7 +9274,7 @@ class LinearFunctionInst final /// DifferentiableFunctionExtractInst - extracts either the original or /// derivative function value from a `@differentiable` function. -class DifferentiableFunctionExtractInst +class __attribute__((swift_attr("import_as_ref"))) DifferentiableFunctionExtractInst : public UnaryInstructionBase< SILInstructionKind::DifferentiableFunctionExtractInst, GuaranteedFirstArgForwardingSingleValueInst> { @@ -9284,7 +9318,7 @@ class DifferentiableFunctionExtractInst /// LinearFunctionExtractInst - given an `@differentiable(_linear)` function /// representing a bundle of the original function and the transpose function, /// extract the specified function. -class LinearFunctionExtractInst +class __attribute__((swift_attr("import_as_ref"))) LinearFunctionExtractInst : public UnaryInstructionBase { private: @@ -9309,7 +9343,7 @@ class LinearFunctionExtractInst /// DifferentiabilityWitnessFunctionInst - Looks up a differentiability witness /// function for a given original function. -class DifferentiabilityWitnessFunctionInst +class __attribute__((swift_attr("import_as_ref"))) DifferentiabilityWitnessFunctionInst : public InstructionBase< SILInstructionKind::DifferentiabilityWitnessFunctionInst, SingleValueInstruction> { @@ -9416,7 +9450,8 @@ SILFunction *ApplyInstBase::getCalleeFunction() const { } /// The first operand is the ownership equivalent source. -class OwnershipForwardingMultipleValueInstruction +class __attribute__((swift_attr("import_as_ref"))) +OwnershipForwardingMultipleValueInstruction : public MultipleValueInstruction, public OwnershipForwardingMixin { public: @@ -9449,7 +9484,7 @@ class OwnershipForwardingMultipleValueInstruction /// Instruction that takes in a struct value and splits the struct into the /// struct's fields. -class DestructureStructInst final +class __attribute__((swift_attr("import_as_ref"))) DestructureStructInst final : public UnaryInstructionBase, public MultipleValueInstructionTrailingObjects { @@ -9473,7 +9508,7 @@ class DestructureStructInst final /// Instruction that takes in a tuple value and splits the tuple into the /// tuples's elements. -class DestructureTupleInst final +class __attribute__((swift_attr("import_as_ref"))) DestructureTupleInst final : public UnaryInstructionBase, public MultipleValueInstructionTrailingObjects { diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h index e6746c2aa8a71..3193363a95fe6 100644 --- a/include/swift/SIL/SILNode.h +++ b/include/swift/SIL/SILNode.h @@ -115,7 +115,7 @@ class SILNodePointer { /// subobject. If the SILNode is actually the base subobject of a /// ValueBase subobject, the cast will yield a corrupted value. /// Always use the LLVM casts (cast<>, dyn_cast<>, etc.) instead. -class alignas(8) SILNode : +class __attribute__((swift_attr("import_as_ref"))) alignas(8) SILNode : // SILNode contains a swift object header for bridging with libswift. // For details see libswift/README.md. public SwiftObjectHeader { @@ -469,7 +469,6 @@ class alignas(8) SILNode : // of the cast machinery. At a high level, all you need to know is to // never use static_cast to downcast a SILNode. SILInstruction *castToInstruction(); - const SILInstruction *castToInstruction() const; static SILNode *instAsNode(SILInstruction *inst); static const SILNode *instAsNode(const SILInstruction *inst); diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index 0747aa231622d..97a6e9b760972 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -236,7 +236,13 @@ class SILType { NominalTypeDecl *getNominalOrBoundGenericNominal() const { return getASTType().getNominalOrBoundGenericNominal(); } - + + /// If this type maps to a Swift class, check if that class is a foreign + /// reference type. + bool isForeignReferenceType() const { + return getASTType().isForeignReferenceType(); + } + /// True if the type is an address type. bool isAddress() const { return getCategory() == SILValueCategory::Address; } diff --git a/include/swift/SIL/SILUndef.h b/include/swift/SIL/SILUndef.h index ecbf54df084aa..c99425af53828 100644 --- a/include/swift/SIL/SILUndef.h +++ b/include/swift/SIL/SILUndef.h @@ -22,7 +22,7 @@ class SILArgument; class SILInstruction; class SILModule; -class SILUndef : public ValueBase { +class __attribute__((swift_attr("import_as_ref"))) SILUndef : public ValueBase { SILUndef(SILType type); public: diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h index 0cb6153716453..ee24f410138fa 100644 --- a/include/swift/SIL/SILValue.h +++ b/include/swift/SIL/SILValue.h @@ -339,7 +339,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, ValueOwnershipKind Kind); /// This is the base class of the SIL value hierarchy, which represents a /// runtime computed value. Some examples of ValueBase are SILArgument and /// SingleValueInstruction. -class ValueBase : public SILNode, public SILAllocated { +class __attribute__((swift_attr("import_as_ref"))) ValueBase + : public SILNode, public SILAllocated { friend class Operand; SILType Type; @@ -1434,7 +1435,8 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SILValue V) { /// Used internally in e.g. the SIL parser and deserializer to handle forward- /// referenced values. /// A PlaceholderValue must not appear in valid SIL. -class PlaceholderValue : public ValueBase { +class __attribute__((swift_attr("import_as_ref"))) PlaceholderValue + : public ValueBase { static int numPlaceholderValuesAlive; public: diff --git a/include/swift/SILOptimizer/OptimizerBridging.h b/include/swift/SILOptimizer/OptimizerBridging.h index 3185b80f76621..7fce691e5fb43 100644 --- a/include/swift/SILOptimizer/OptimizerBridging.h +++ b/include/swift/SILOptimizer/OptimizerBridging.h @@ -22,12 +22,12 @@ extern "C" { #endif typedef struct { - BridgedFunction function; + SILFunction *function; BridgedPassContext passContext; } BridgedFunctionPassCtxt; typedef struct { - BridgedInstruction instruction; + SILInstruction *instruction; BridgedPassContext passContext; } BridgedInstructionPassCtxt; @@ -59,16 +59,15 @@ SwiftInt PassContext_isSwift51RuntimeAvailable(BridgedPassContext context); BridgedAliasAnalysis PassContext_getAliasAnalysis(BridgedPassContext context); BridgedMemoryBehavior AliasAnalysis_getMemBehavior(BridgedAliasAnalysis aa, - BridgedInstruction inst, - BridgedValue addr); + SILInstruction *inst, + ValueBase *addr); BridgedCalleeAnalysis PassContext_getCalleeAnalysis(BridgedPassContext context); BridgedCalleeList CalleeAnalysis_getCallees(BridgedCalleeAnalysis calleeAnalysis, - BridgedValue callee); + ValueBase *callee); SwiftInt BridgedFunctionArray_size(BridgedCalleeList callees); -BridgedFunction BridgedFunctionArray_get(BridgedCalleeList callees, - SwiftInt index); +SILFunction *BridgedFunctionArray_get(BridgedCalleeList callees, SwiftInt index); #ifdef __cplusplus } // extern "C" diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 76ddd8a4a014d..6e533e1ab89e5 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -545,7 +545,8 @@ ClangTypeConverter::visitBoundGenericType(BoundGenericType *type) { auto args = type->getGenericArgs(); assert((args.size() == 1) && "Optional should have 1 generic argument."); clang::QualType innerTy = convert(args[0]); - if (swift::canImportAsOptional(innerTy.getTypePtrOrNull())) + if (swift::canImportAsOptional(innerTy.getTypePtrOrNull()) || + args[0]->isForeignReferenceType()) return innerTy; return clang::QualType(); } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 36db5d2aafdf5..5188d8f34df0c 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1940,7 +1940,11 @@ static bool isPolymorphic(const AbstractStorageDecl *storage) { return true; if (auto *classDecl = dyn_cast(storage->getDeclContext())) { - if (storage->isFinal() || classDecl->isFinal()) + // Accesses to members of foreign reference types should be made directly + // to storage as these are references to clang records which are not allowed + // to have dynamic dispatch. + if (storage->isFinal() || classDecl->isFinal() || + classDecl->isForeignReferenceType()) return false; return true; @@ -4720,6 +4724,10 @@ bool ClassDecl::walkSuperclasses( return false; } +bool ClassDecl::isForeignReferenceType() { + return getClangDecl() && isa(getClangDecl()); +} + EnumCaseDecl *EnumCaseDecl::create(SourceLoc CaseLoc, ArrayRef Elements, DeclContext *DC) { diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index bbecef03ce454..3913d897bba2d 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -4443,11 +4443,8 @@ bool GenericSignatureBuilder::updateSuperclass( auto layoutReqSource = source.getSource(*this, type)->viaLayout(*this, superclass); - auto layout = - LayoutConstraint::getLayoutConstraint( - superclass->getClassOrBoundGenericClass()->usesObjCObjectModel() - ? LayoutConstraintKind::Class - : LayoutConstraintKind::NativeClass, + auto layout = LayoutConstraint::getLayoutConstraint( + superclass->getClassOrBoundGenericClass()->getLayoutConstraintKind(), getASTContext()); addLayoutRequirementDirect(type, layout, layoutReqSource); return true; diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index 8690329f33f6c..4542e43d946bb 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -1478,7 +1478,7 @@ DirectLookupRequest::evaluate(Evaluator &evaluator, } else if (isa_and_nonnull(decl->getClangDecl())) { auto allFound = evaluateOrDefault( ctx.evaluator, - ClangRecordMemberLookup({cast(decl), name}), {}); + ClangRecordMemberLookup({cast(decl), name}), {}); // Add all the members we found, later we'll combine these with the // existing members. for (auto found : allFound) diff --git a/lib/AST/RequirementMachine/RequirementLowering.cpp b/lib/AST/RequirementMachine/RequirementLowering.cpp index c1cb623e7a9a0..c4ec91107b037 100644 --- a/lib/AST/RequirementMachine/RequirementLowering.cpp +++ b/lib/AST/RequirementMachine/RequirementLowering.cpp @@ -523,9 +523,7 @@ void RuleBuilder::addRequirement(const Requirement &req, // Build the symbol [layout: L]. auto layout = LayoutConstraint::getLayoutConstraint( - otherType->getClassOrBoundGenericClass()->usesObjCObjectModel() - ? LayoutConstraintKind::Class - : LayoutConstraintKind::NativeClass, + otherType->getClassOrBoundGenericClass()->getLayoutConstraintKind(), Context.getASTContext()); auto layoutSymbol = Symbol::forLayout(layout, Context); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index e28c74886944a..4d9c5867f8c1b 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -758,7 +758,7 @@ Type TypeBase::lookThroughAllOptionalTypes(SmallVectorImpl &optionals){ bool TypeBase::isAnyObject() { auto canTy = getCanonicalType(); - if (!canTy.isExistentialType()) + if (!canTy.isExistentialType() || canTy.isForeignReferenceType()) return false; return canTy.getExistentialLayout().isAnyObject(); @@ -5274,12 +5274,6 @@ bool UnownedStorageType::isLoadable(ResilienceExpansion resilience) const { return ty->getReferenceCounting() == ReferenceCounting::Native; } -static ReferenceCounting getClassReferenceCounting(ClassDecl *theClass) { - return (theClass->usesObjCObjectModel() - ? ReferenceCounting::ObjC - : ReferenceCounting::Native); -} - ReferenceCounting TypeBase::getReferenceCounting() { CanType type = getCanonicalType(); ASTContext &ctx = type->getASTContext(); @@ -5306,13 +5300,12 @@ ReferenceCounting TypeBase::getReferenceCounting() { return ReferenceCounting::Bridge; case TypeKind::Class: - return getClassReferenceCounting(cast(type)->getDecl()); + return cast(type)->getDecl()->getObjectModel(); case TypeKind::BoundGenericClass: - return getClassReferenceCounting( - cast(type)->getDecl()); + return cast(type)->getDecl()->getObjectModel(); case TypeKind::UnboundGeneric: - return getClassReferenceCounting( - cast(cast(type)->getDecl())); + return cast(cast(type)->getDecl()) + ->getObjectModel(); case TypeKind::DynamicSelf: return cast(type).getSelfType() @@ -5524,6 +5517,16 @@ TypeBase::getAutoDiffTangentSpace(LookupConformanceFn lookupConformance) { return cache(None); } +bool TypeBase::isForeignReferenceType() { + return getCanonicalType().isForeignReferenceType(); +} + +bool CanType::isForeignReferenceType() { + if (auto *classDecl = getPointer()->lookThroughAllOptionalTypes()->getClassOrBoundGenericClass()) + return classDecl->isForeignReferenceType(); + return false; +} + // Creates an `AnyFunctionType` from the given parameters, result type, // generic signature, and `ExtInfo`. static AnyFunctionType * diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 076c6a87bdd70..43a28f41a64d3 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -4121,7 +4121,7 @@ TinyPtrVector CXXNamespaceMemberLookup::evaluate( TinyPtrVector ClangRecordMemberLookup::evaluate( Evaluator &evaluator, ClangRecordMemberLookupDescriptor desc) const { - StructDecl *recordDecl = desc.recordDecl; + NominalTypeDecl *recordDecl = desc.recordDecl; DeclName name = desc.name; auto &ctx = recordDecl->getASTContext(); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index b3ab45d7ca28d..c6d37caa8eb2f 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -705,7 +705,7 @@ static AccessorDecl *makeStructRawValueGetter( } static AccessorDecl *makeFieldGetterDecl(ClangImporter::Implementation &Impl, - StructDecl *importedDecl, + NominalTypeDecl *importedDecl, VarDecl *importedFieldDecl, ClangNode clangNode = ClangNode()) { auto &C = Impl.SwiftContext; @@ -733,7 +733,7 @@ static AccessorDecl *makeFieldGetterDecl(ClangImporter::Implementation &Impl, } static AccessorDecl *makeFieldSetterDecl(ClangImporter::Implementation &Impl, - StructDecl *importedDecl, + NominalTypeDecl *importedDecl, VarDecl *importedFieldDecl, ClangNode clangNode = ClangNode()) { auto &C = Impl.SwiftContext; @@ -875,7 +875,7 @@ static std::pair makeIndirectFieldAccessors(ClangImporter::Implementation &Impl, const clang::IndirectFieldDecl *indirectField, ArrayRef members, - StructDecl *importedStructDecl, + NominalTypeDecl *importedStructDecl, VarDecl *importedFieldDecl) { auto &C = Impl.SwiftContext; @@ -1042,7 +1042,7 @@ synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) { /// \returns a pair of the getter and setter function decls. static std::pair makeUnionFieldAccessors(ClangImporter::Implementation &Impl, - StructDecl *importedUnionDecl, + NominalTypeDecl *importedUnionDecl, VarDecl *importedFieldDecl) { auto &C = Impl.SwiftContext; @@ -1066,7 +1066,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl, static clang::DeclarationName getAccessorDeclarationName(clang::ASTContext &Ctx, - StructDecl *structDecl, + NominalTypeDecl *structDecl, VarDecl *fieldDecl, const char *suffix) { std::string id; @@ -1094,7 +1094,7 @@ getAccessorDeclarationName(clang::ASTContext &Ctx, static std::pair makeBitFieldAccessors(ClangImporter::Implementation &Impl, clang::RecordDecl *structDecl, - StructDecl *importedStructDecl, + NominalTypeDecl *importedStructDecl, clang::FieldDecl *fieldDecl, VarDecl *importedFieldDecl) { clang::ASTContext &Ctx = Impl.getClangASTContext(); @@ -1301,7 +1301,7 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd, /// Create a default constructor that initializes a struct to zero. static ConstructorDecl * createDefaultConstructor(ClangImporter::Implementation &Impl, - StructDecl *structDecl) { + NominalTypeDecl *structDecl) { auto &context = Impl.SwiftContext; auto emptyPL = ParameterList::createEmpty(context); @@ -1396,7 +1396,7 @@ synthesizeValueConstructorBody(AbstractFunctionDecl *afd, void *context) { /// Create a constructor that initializes a struct from its members. static ConstructorDecl * createValueConstructor(ClangImporter::Implementation &Impl, - StructDecl *structDecl, ArrayRef members, + NominalTypeDecl *structDecl, ArrayRef members, bool wantCtorParamNames, bool wantBody) { auto &context = Impl.SwiftContext; @@ -2432,24 +2432,29 @@ namespace { } Decl *VisitNamespaceDecl(const clang::NamespaceDecl *decl) { - DeclContext *dc = nullptr; - // If this is a top-level namespace, don't put it in the module we're - // importing, put it in the "__ObjC" module that is implicitly imported. - if (!decl->getParent()->isNamespace()) - dc = Impl.ImportedHeaderUnit; - else { - // This is a nested namespace, so just lookup it's parent normally. - auto parentNS = cast(decl->getParent()); - auto parent = - Impl.importDecl(parentNS, getVersion(), /*UseCanonicalDecl*/ false); - dc = cast(parent); - } +// DeclContext *dc = nullptr; +// // If this is a top-level namespace, don't put it in the module we're +// // importing, put it in the "__ObjC" module that is implicitly imported. +// if (!decl->getParent()->isNamespace()) +// dc = Impl.ImportedHeaderUnit; +// else { +// // This is a nested namespace, so just lookup it's parent normally. +// auto parentNS = cast(decl->getParent()); +// auto parent = +// Impl.importDecl(parentNS, getVersion(), /*UseCanonicalDecl*/ false); +// dc = cast(parent); +// } ImportedName importedName; std::tie(importedName, std::ignore) = importFullName(decl); // If we don't have a name for this declaration, bail. We can't import it. if (!importedName) return nullptr; + + auto dc = + Impl.importDeclContextOf(decl, importedName.getEffectiveContext()); + if (!dc) + return nullptr; auto *enumDecl = Impl.createDeclWithClangNode( decl, AccessLevel::Public, Impl.importSourceLoc(decl->getBeginLoc()), @@ -3276,7 +3281,18 @@ namespace { return result; } + static bool hasImportAsRefAttr(const clang::RecordDecl *decl) { + return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) { + if (auto swiftAttr = dyn_cast(attr)) + return swiftAttr->getAttribute() == "import_as_ref"; + return false; + }); + } + bool isCxxRecordImportable(const clang::CXXRecordDecl *decl) { + if (hasImportAsRefAttr(decl)) + return true; + if (auto dtor = decl->getDestructor()) { if (dtor->isDeleted() || dtor->getAccess() != clang::AS_public) { return false; @@ -3370,7 +3386,7 @@ namespace { // Create the struct declaration and record it. auto name = importedName.getDeclName().getBaseIdentifier(); - StructDecl *result = nullptr; + NominalTypeDecl *result = nullptr; // Try to find an already-imported struct. This case happens any time // there are nested structs. The "Parent" struct will import the "Child" // struct at which point it attempts to import its decl context which is @@ -3380,9 +3396,15 @@ namespace { Impl.ImportedDecls.find({decl->getCanonicalDecl(), getVersion()}); if (alreadyImportedResult != Impl.ImportedDecls.end()) return alreadyImportedResult->second; - result = Impl.createDeclWithClangNode( - decl, AccessLevel::Public, Impl.importSourceLoc(decl->getBeginLoc()), - name, Impl.importSourceLoc(decl->getLocation()), None, nullptr, dc); + + auto loc = Impl.importSourceLoc(decl->getLocation()); + if (hasImportAsRefAttr(decl)) + result = Impl.createDeclWithClangNode( + decl, AccessLevel::Public, loc, name, loc, + ArrayRef{}, nullptr, dc, false); + else + result = Impl.createDeclWithClangNode( + decl, AccessLevel::Public, loc, name, loc, None, nullptr, dc); Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result; // FIXME: Figure out what to do with superclasses in C++. One possible @@ -3542,16 +3564,23 @@ namespace { ctors.push_back(valueCtor); } - // Add ctors directly as they cannot always be looked up from the clang - // decl (some are synthesized by Swift). - for (auto ctor : ctors) { - result->addMember(ctor); + // Do not allow Swift to construct foreign reference types (at least, not + // yet). + if (isa(result)) { + for (auto ctor : ctors) { + // Add ctors directly as they cannot always be looked up from the + // clang decl (some are synthesized by Swift). + result->addMember(ctor); + } } - result->setHasUnreferenceableStorage(hasUnreferenceableStorage); + if (auto structResult = dyn_cast(result)) + structResult->setHasUnreferenceableStorage(hasUnreferenceableStorage); if (cxxRecordDecl) { - result->setIsCxxNonTrivial(!cxxRecordDecl->isTriviallyCopyable()); + if (auto structResult = dyn_cast(result)) + structResult->setIsCxxNonTrivial( + !cxxRecordDecl->isTriviallyCopyable()); for (auto &subscriptInfo : Impl.cxxSubscripts) { auto declAndParameterType = subscriptInfo.first; @@ -3865,6 +3894,26 @@ namespace { VarDecl *getImplicitProperty(ImportedName importedName, const clang::FunctionDecl *accessor); + static bool + foreignReferenceTypePassedByRef(const clang::FunctionDecl *decl) { + bool anyParamPassesByVal = + llvm::any_of(decl->parameters(), [](auto *param) { + if (auto recordType = dyn_cast( + param->getType().getCanonicalType())) + return hasImportAsRefAttr(recordType->getDecl()); + return false; + }); + + if (anyParamPassesByVal) + return true; + + if (auto recordType = dyn_cast( + decl->getReturnType().getCanonicalType())) + return hasImportAsRefAttr(recordType->getDecl()); + + return false; + } + Decl *VisitFunctionDecl(const clang::FunctionDecl *decl) { // Import the name of the function. ImportedName importedName; @@ -3873,6 +3922,11 @@ namespace { if (!importedName) return nullptr; + // Don't import functions that pass a foreign reference type by value + // (either as a parameter or return type). + if (foreignReferenceTypePassedByRef(decl)) + return nullptr; + AbstractStorageDecl *owningStorage; switch (importedName.getAccessorKind()) { case ImportedAccessorKind::None: @@ -4048,10 +4102,13 @@ namespace { selfIdx = None; } else { selfIdx = 0; + // Don't import members of a class decl as mutating. // If the method is imported as mutating, this implicitly makes the // parameter indirect. - selfIsInOut = Impl.SwiftContext.getClangModuleLoader() - ->isCXXMethodMutating(mdecl); + selfIsInOut = + !isa(dc) && + Impl.SwiftContext.getClangModuleLoader()->isCXXMethodMutating( + mdecl); } } } @@ -4208,6 +4265,14 @@ namespace { if (!dc) return nullptr; + // TODO: do we want to emit a diagnostic here? + // Types that are marked as foreign references cannot be stored by value. + if (auto recordType = + dyn_cast(decl->getType().getCanonicalType())) { + if (hasImportAsRefAttr(recordType->getDecl())) + return nullptr; + } + auto importedType = Impl.importType(decl->getType(), ImportTypeKind::RecordField, isInSystemModule(dc), Bridgeability::None); @@ -9706,7 +9771,7 @@ static void loadAllMembersOfSuperclassIfNeeded(ClassDecl *CD) { E->loadAllMembers(); } -static void loadAllMembersOfRecordDecl(StructDecl *recordDecl) { +static void loadAllMembersOfRecordDecl(NominalTypeDecl *recordDecl) { auto &ctx = recordDecl->getASTContext(); auto clangRecord = cast(recordDecl->getClangDecl()); @@ -9735,8 +9800,12 @@ static void loadAllMembersOfRecordDecl(StructDecl *recordDecl) { continue; for (auto found : recordDecl->lookupDirect(name)) { - if (addedMembers.insert(found).second) - recordDecl->addMember(found); + if (addedMembers.insert(found).second) { + // TODO: + // assert(found->getDeclContext()->getAsDecl() == recordDecl); + if (found->getDeclContext()->getAsDecl() == recordDecl) + recordDecl->addMember(found); + } } } } @@ -9775,8 +9844,8 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) { if (isa_and_nonnull(D->getClangDecl())) { // TODO: this is a hack to set member loading as lazy again. It got set to // non-lazy when getMembers was called. - cast(D)->setMemberLoader(this, 0); - loadAllMembersOfRecordDecl(cast(D)); + cast(D)->setMemberLoader(this, 0); + loadAllMembersOfRecordDecl(cast(D)); return; } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 2847baa21c4b4..4416eadcc383e 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -452,6 +452,10 @@ namespace { pointeeQualType, ImportTypeKind::Value, AllowNSUIntegerAsInt, Bridgeability::None); + // If this is imported as a reference type, ignore the pointer. + if (pointeeType && pointeeType->isForeignReferenceType()) + return {pointeeType, ImportHint::OtherPointer}; + // If the pointed-to type is unrepresentable in Swift, or its C // alignment is greater than the maximum Swift alignment, import as // OpaquePointer. @@ -524,6 +528,9 @@ namespace { if (!pointeeType) return Type(); + if (pointeeType->isForeignReferenceType()) + return {pointeeType, ImportHint::None}; + if (pointeeQualType->isFunctionType()) { return importFunctionPointerLikeType(*type, pointeeType); } @@ -1516,7 +1523,8 @@ static ImportedType adjustTypeForConcreteImport( assert(importedType); if (importKind == ImportTypeKind::RecordField && - importedType->isAnyClassReferenceType()) { + importedType->isAnyClassReferenceType() && + !importedType->isForeignReferenceType()) { // Wrap retainable struct fields in Unmanaged. // FIXME: Eventually we might get C++-like support for strong pointers in // structs, at which point we should really be checking the lifetime @@ -1959,8 +1967,11 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList( param, AccessLevel::Private, SourceLoc(), SourceLoc(), name, importSourceLoc(param->getLocation()), bodyName, ImportedHeaderUnit); - paramInfo->setSpecifier(isInOut ? ParamSpecifier::InOut - : ParamSpecifier::Default); + // Foreign references are already references so they don't need to be passed + // as inout. + paramInfo->setSpecifier(isInOut && !swiftParamTy->isForeignReferenceType() + ? ParamSpecifier::InOut + : ParamSpecifier::Default); paramInfo->setInterfaceType(swiftParamTy); recordImplicitUnwrapForDecl(paramInfo, isParamTypeImplicitlyUnwrapped); parameters.push_back(paramInfo); diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 4dbcdeb177aee..6b794c0b0c536 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -1448,7 +1448,7 @@ void SignatureExpansion::expandExternalSignatureTypes() { auto paramTy = getSILFuncConventions().getSILType( param, IGM.getMaximalTypeExpansionContext()); auto ¶mTI = cast(IGM.getTypeInfo(paramTy)); - if (AI.getIndirectByVal()) { + if (AI.getIndirectByVal() && !paramTy.isForeignReferenceType()) { addByvalArgumentAttributes( IGM, Attrs, getCurParamIndex(), Alignment(AI.getIndirectAlign().getQuantity()), @@ -2260,7 +2260,7 @@ class SyncCallEmission final : public CallEmission { if (fnConv.getNumDirectSILResults() == 1 && (fnConv.getDirectSILResults().begin()->getConvention() == ResultConvention::Autoreleased)) { - result = emitObjCRetainAutoreleasedReturnValue(IGF, result); +// result = emitObjCRetainAutoreleasedReturnValue(IGF, result); } auto origFnType = getCallee().getOrigFunctionType(); @@ -3531,6 +3531,20 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, SILType paramType = silConv.getSILType( params[i - firstParam], IGF.IGM.getMaximalTypeExpansionContext()); + + // In Swift, values that are foreign references types will always be + // pointers. Additionally, we only import functions which use foreign + // reference types indirectly (as pointers), so we know in every case, if + // the argument type is a foreign reference type, the types will match up + // and we can simply use the input directly. + if (paramType.isForeignReferenceType()) { + auto *arg = in.claimNext(); + if (isIndirectFormalParameter(params[i - firstParam].getConvention())) + arg = IGF.Builder.CreateLoad(arg, IGF.IGM.getPointerAlignment()); + out.add(arg); + continue; + } + switch (AI.getKind()) { case clang::CodeGen::ABIArgInfo::Extend: { bool signExt = clangParamTy->hasSignedIntegerRepresentation(); diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 40c8b3a5263da..73691c781dce9 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -147,6 +147,8 @@ namespace { addNSObjectHeader(); HeaderSize = CurSize; break; + case ReferenceCounting::None: + break; case ReferenceCounting::Block: case ReferenceCounting::Unknown: case ReferenceCounting::Bridge: @@ -215,7 +217,7 @@ namespace { void addFieldsForClassImpl(ClassDecl *rootClass, SILType rootClassType, ClassDecl *theClass, SILType classType, bool superclass) { - if (theClass->hasClangNode()) { + if (theClass->hasClangNode() && !theClass->isForeignReferenceType()) { Options |= ClassMetadataFlags::ClassHasObjCAncestry; return; } diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 8dc2cfd6ead6f..a445f3c2ee11a 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -3663,7 +3663,7 @@ IRGenModule::getTypeEntityReference(GenericTypeDecl *decl) { if (auto nominal = dyn_cast(decl)) { auto clas = dyn_cast(decl); - if (!clas) { + if (!clas || clas->isForeignReferenceType()) { return getTypeContextDescriptorEntityReference(*this, nominal); } diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp index 4f6a27b1fe32e..c880519d634d6 100644 --- a/lib/IRGen/GenHeap.cpp +++ b/lib/IRGen/GenHeap.cpp @@ -584,6 +584,7 @@ unsigned IRGenModule::getReferenceStorageExtraInhabitantCount( return getHeapObjectExtraInhabitantCount(*this); case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -613,6 +614,7 @@ SpareBitVector IRGenModule::getReferenceStorageSpareBits( return getHeapObjectSpareBits(); case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -642,6 +644,7 @@ APInt IRGenModule::getReferenceStorageExtraInhabitantValue(unsigned bits, return getHeapObjectFixedExtraInhabitantValue(*this, bits, index, 0); case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -662,6 +665,7 @@ APInt IRGenModule::getReferenceStorageExtraInhabitantMask( case ReferenceCounting::Native: case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -681,6 +685,7 @@ llvm::Value *IRGenFunction::getReferenceStorageExtraInhabitantIndex(Address src, return getHeapObjectExtraInhabitantIndex(*this, src); case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -717,6 +722,7 @@ void IRGenFunction::storeReferenceStorageExtraInhabitant(llvm::Value *index, return storeHeapObjectExtraInhabitant(*this, index, dest); case ReferenceCounting::Block: case ReferenceCounting::ObjC: + case ReferenceCounting::None: case ReferenceCounting::Unknown: break; case ReferenceCounting::Bridge: @@ -738,35 +744,30 @@ void IRGenFunction::storeReferenceStorageExtraInhabitant(llvm::Value *index, Builder.CreateStore(null, dest); } -#define SOMETIMES_UNKNOWN(Name) \ - const TypeInfo * \ - TypeConverter::create##Name##StorageType(llvm::Type *valueType, \ - ReferenceCounting style, \ - bool isOptional) { \ - auto &&spareBits = IGM.getReferenceStorageSpareBits( \ - ReferenceOwnership::Name, style); \ - switch (style) { \ - case ReferenceCounting::Native: \ - return new Native##Name##ReferenceTypeInfo(valueType, \ - IGM.Name##ReferencePtrTy->getElementType(), \ - IGM.getPointerSize(), \ - IGM.getPointerAlignment(), \ - std::move(spareBits), \ - isOptional); \ - case ReferenceCounting::ObjC: \ - case ReferenceCounting::Block: \ - case ReferenceCounting::Unknown: \ - return new Unknown##Name##ReferenceTypeInfo(valueType, \ - IGM.Name##ReferencePtrTy->getElementType(), \ - IGM.getPointerSize(), \ - IGM.getPointerAlignment(), \ - std::move(spareBits), \ - isOptional); \ - case ReferenceCounting::Bridge: \ - case ReferenceCounting::Error: \ - llvm_unreachable("not supported!"); \ - } \ - llvm_unreachable("bad reference-counting style"); \ +#define SOMETIMES_UNKNOWN(Name) \ + const TypeInfo *TypeConverter::create##Name##StorageType( \ + llvm::Type *valueType, ReferenceCounting style, bool isOptional) { \ + auto &&spareBits = \ + IGM.getReferenceStorageSpareBits(ReferenceOwnership::Name, style); \ + switch (style) { \ + case ReferenceCounting::Native: \ + return new Native##Name##ReferenceTypeInfo( \ + valueType, IGM.Name##ReferencePtrTy->getElementType(), \ + IGM.getPointerSize(), IGM.getPointerAlignment(), \ + std::move(spareBits), isOptional); \ + case ReferenceCounting::ObjC: \ + case ReferenceCounting::None: \ + case ReferenceCounting::Block: \ + case ReferenceCounting::Unknown: \ + return new Unknown##Name##ReferenceTypeInfo( \ + valueType, IGM.Name##ReferencePtrTy->getElementType(), \ + IGM.getPointerSize(), IGM.getPointerAlignment(), \ + std::move(spareBits), isOptional); \ + case ReferenceCounting::Bridge: \ + case ReferenceCounting::Error: \ + llvm_unreachable("not supported!"); \ + } \ + llvm_unreachable("bad reference-counting style"); \ } #define ALWAYS_NATIVE(Name) \ const TypeInfo * \ @@ -1011,6 +1012,8 @@ void IRGenFunction::emitStrongRelease(llvm::Value *value, return emitBridgeStrongRelease(value, atomicity); case ReferenceCounting::Error: return emitErrorStrongRelease(value); + case ReferenceCounting::None: + return; // This is a no-op if we don't have any ref-counting. } } @@ -1036,6 +1039,8 @@ void IRGenFunction::emitStrongRetain(llvm::Value *value, case ReferenceCounting::Error: emitErrorStrongRetain(value); return; + case ReferenceCounting::None: + return; // This is a no-op if we don't have any ref-counting. } } @@ -1053,43 +1058,47 @@ llvm::Type *IRGenModule::getReferenceType(ReferenceCounting refcounting) { return UnknownRefCountedPtrTy; case ReferenceCounting::Error: return ErrorPtrTy; + case ReferenceCounting::None: + return OpaquePtrTy; } llvm_unreachable("Not a valid ReferenceCounting."); } #define DEFINE_BINARY_OPERATION(KIND, RESULT, TYPE1, TYPE2) \ -RESULT IRGenFunction::emit##KIND(TYPE1 val1, TYPE2 val2, \ - ReferenceCounting style) { \ - switch (style) { \ - case ReferenceCounting::Native: \ - return emitNative##KIND(val1, val2); \ - case ReferenceCounting::ObjC: \ - case ReferenceCounting::Unknown: \ - return emitUnknown##KIND(val1, val2); \ - case ReferenceCounting::Bridge: \ - case ReferenceCounting::Block: \ - case ReferenceCounting::Error: \ - llvm_unreachable("unsupported reference kind with reference storage"); \ - } \ - llvm_unreachable("bad refcounting style"); \ -} + RESULT IRGenFunction::emit##KIND(TYPE1 val1, TYPE2 val2, \ + ReferenceCounting style) { \ + switch (style) { \ + case ReferenceCounting::Native: \ + return emitNative##KIND(val1, val2); \ + case ReferenceCounting::ObjC: \ + case ReferenceCounting::Unknown: \ + return emitUnknown##KIND(val1, val2); \ + case ReferenceCounting::Bridge: \ + case ReferenceCounting::Block: \ + case ReferenceCounting::Error: \ + case ReferenceCounting::None: \ + llvm_unreachable("unsupported reference kind with reference storage"); \ + } \ + llvm_unreachable("bad refcounting style"); \ + } #define DEFINE_UNARY_OPERATION(KIND, RESULT, TYPE1) \ -RESULT IRGenFunction::emit##KIND(TYPE1 val1, ReferenceCounting style) { \ - switch (style) { \ - case ReferenceCounting::Native: \ - return emitNative##KIND(val1); \ - case ReferenceCounting::ObjC: \ - case ReferenceCounting::Unknown: \ - return emitUnknown##KIND(val1); \ - case ReferenceCounting::Bridge: \ - case ReferenceCounting::Block: \ - case ReferenceCounting::Error: \ - llvm_unreachable("unsupported reference kind with reference storage"); \ - } \ - llvm_unreachable("bad refcounting style"); \ -} + RESULT IRGenFunction::emit##KIND(TYPE1 val1, ReferenceCounting style) { \ + switch (style) { \ + case ReferenceCounting::Native: \ + return emitNative##KIND(val1); \ + case ReferenceCounting::ObjC: \ + case ReferenceCounting::Unknown: \ + return emitUnknown##KIND(val1); \ + case ReferenceCounting::Bridge: \ + case ReferenceCounting::Block: \ + case ReferenceCounting::Error: \ + case ReferenceCounting::None: \ + llvm_unreachable("unsupported reference kind with reference storage"); \ + } \ + llvm_unreachable("bad refcounting style"); \ + } #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ DEFINE_BINARY_OPERATION(Name##CopyInit, void, Address, Address) \ diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index 2733b43d63fff..db6d048051039 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -1624,7 +1624,8 @@ namespace { VTable(IGM.getSILModule().lookUpVTable(getType())), Resilient(IGM.hasResilientMetadata(Type, ResilienceExpansion::Minimal)) { - if (getType()->isForeign()) return; + if (getType()->isForeign() || Type->isForeignReferenceType()) + return; MetadataLayout = &IGM.getClassMetadataLayout(Type); @@ -1655,6 +1656,10 @@ namespace { void layout() { super::layout(); + + if (getType()->isForeignReferenceType()) + return; + addVTable(); addOverrideTable(); addObjCResilientClassStubInfo(); @@ -2430,7 +2435,7 @@ static void emitInitializeValueMetadata(IRGenFunction &IGF, auto loweredTy = IGF.IGM.getLoweredType(nominalDecl->getDeclaredTypeInContext()); - if (isa(nominalDecl)) { + if (isa(nominalDecl) || isa(nominalDecl)) { auto &fixedTI = IGF.IGM.getTypeInfo(loweredTy); if (isa(fixedTI)) return; @@ -5030,6 +5035,13 @@ namespace { void emitInitializeMetadata(IRGenFunction &IGF, llvm::Value *metadata, MetadataDependencyCollector *collector) { + if (getTargetType()->isForeignReferenceType()) { + emitInitializeValueMetadata(IGF, + getTargetType().getClassOrBoundGenericClass(), + metadata, false, collector); + return; + } + if (!Target->hasSuperclass()) { assert(IGM.getOptions().LazyInitializeClassMetadata && "should have superclass if not lazy initializing class metadata"); @@ -5053,6 +5065,12 @@ namespace { // Visitor methods. void addValueWitnessTable() { + if (getTargetType()->isForeignReferenceType()) { + auto type = getTargetType()->getCanonicalType(); + B.add(irgen::emitValueWitnessTable(IGM, type, false, false).getValue()); + return; + } + // The runtime will fill in the default VWT during allocation for the // foreign class metadata. // @@ -5081,7 +5099,11 @@ namespace { } void addMetadataFlags() { - B.addInt(IGM.MetadataKindTy, (unsigned) MetadataKind::ForeignClass); + if (getTargetType()->isForeignReferenceType()) { + B.addInt(IGM.MetadataKindTy, (unsigned) MetadataKind::Struct); + } else { + B.addInt(IGM.MetadataKindTy, (unsigned) MetadataKind::ForeignClass); + } } void addNominalTypeDescriptor() { @@ -5173,6 +5195,9 @@ bool irgen::requiresForeignTypeMetadata(CanType type) { bool irgen::requiresForeignTypeMetadata(NominalTypeDecl *decl) { if (auto *clas = dyn_cast(decl)) { + if (clas->isForeignReferenceType()) + return true; + switch (clas->getForeignClassKind()) { case ClassDecl::ForeignKind::Normal: case ClassDecl::ForeignKind::RuntimeOnly: @@ -5196,7 +5221,8 @@ void irgen::emitForeignTypeMetadata(IRGenModule &IGM, NominalTypeDecl *decl) { init.setPacked(true); if (auto classDecl = dyn_cast(decl)) { - assert(classDecl->getForeignClassKind() == ClassDecl::ForeignKind::CFType); + assert(classDecl->getForeignClassKind() == ClassDecl::ForeignKind::CFType || + classDecl->isForeignReferenceType()); ForeignClassMetadataBuilder builder(IGM, classDecl, init); builder.layout(); diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index ff511d5e42065..0a5c9c27e9010 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -1563,6 +1563,7 @@ IRGenModule::getReferenceObjectTypeInfo(ReferenceCounting refcounting) { case ReferenceCounting::Block: case ReferenceCounting::Error: case ReferenceCounting::ObjC: + case ReferenceCounting::None: llvm_unreachable("not implemented"); } diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp index 257b7692c0a7e..8c091b3ce439f 100644 --- a/lib/IRGen/GenValueWitness.cpp +++ b/lib/IRGen/GenValueWitness.cpp @@ -1162,6 +1162,7 @@ getAddrOfKnownValueWitnessTable(IRGenModule &IGM, CanType type, witnessSurrogate = C.TheBridgeObjectType; break; case ReferenceCounting::Error: + case ReferenceCounting::None: break; } } diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp index 56a7e68633ec2..ea92243bb26b8 100644 --- a/lib/IRGen/IRGenMangler.cpp +++ b/lib/IRGen/IRGenMangler.cpp @@ -122,7 +122,8 @@ IRGenMangler::withSymbolicReferences(IRGenModule &IGM, return true; // Foreign class types can be symbolically referenced. - if (clas->getForeignClassKind() == ClassDecl::ForeignKind::CFType) + if (clas->getForeignClassKind() == ClassDecl::ForeignKind::CFType || + const_cast(clas)->isForeignReferenceType()) return true; // Otherwise no. diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index 6d7f6357a79fe..e7be1f177a09c 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -823,6 +823,7 @@ class IRGenModule { case ReferenceCounting::Unknown: case ReferenceCounting::ObjC: case ReferenceCounting::Block: + case ReferenceCounting::None: return true; case ReferenceCounting::Bridge: diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 245e2aae82efc..79f9a7b590154 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2135,7 +2135,9 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) { selfTy = metaTy.getInstanceType(); switch (metaTy->getRepresentation()) { case MetatypeRepresentation::Thin: - llvm_unreachable("class metatypes are never thin"); + assert(selfTy.isForeignReferenceType()); + selfKind = IRGenFunction::ObjectReference; + break; case MetatypeRepresentation::Thick: selfKind = IRGenFunction::SwiftMetatype; break; diff --git a/lib/IRGen/MetadataLayout.cpp b/lib/IRGen/MetadataLayout.cpp index d136f1131a751..35ea3242a23f2 100644 --- a/lib/IRGen/MetadataLayout.cpp +++ b/lib/IRGen/MetadataLayout.cpp @@ -112,7 +112,8 @@ MetadataLayout &IRGenModule::getMetadataLayout(NominalTypeDecl *decl) { auto &entry = MetadataLayouts[decl]; if (!entry) { if (auto theClass = dyn_cast(decl)) { - if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType) + if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType || + theClass->isForeignReferenceType()) entry = new ForeignClassMetadataLayout(*this, theClass); else entry = new ClassMetadataLayout(*this, theClass); @@ -480,7 +481,8 @@ ClassMetadataLayout::getFieldOffsetVectorOffset(IRGenFunction &IGF) const { Size irgen::getClassFieldOffsetOffset(IRGenModule &IGM, ClassDecl *theClass, VarDecl *field) { - if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType) + if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType || + theClass->isForeignReferenceType()) return Size(); return IGM.getClassMetadataLayout(theClass).getStaticFieldOffset(field); @@ -679,7 +681,8 @@ StructMetadataLayout::getTrailingFlagsOffset() const { ForeignClassMetadataLayout::ForeignClassMetadataLayout(IRGenModule &IGM, ClassDecl *theClass) : MetadataLayout(Kind::ForeignClass), Class(theClass) { - assert(theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType && + assert(theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType || + theClass->isForeignReferenceType() && "Not a foreign class"); struct Scanner : LayoutScanner { diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 21ff16f54e6c4..a6198e5fac710 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -3249,6 +3249,9 @@ namespace { case ReferenceCounting::Bridge: case ReferenceCounting::Error: llvm_unreachable("classes shouldn't have this kind of refcounting"); + case ReferenceCounting::None: + llvm_unreachable( + "Foreign reference types don't conform to 'AnyClass'."); } llvm_unreachable("Not a valid ReferenceCounting."); diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp index 98803ea8e88a8..4bdd547483b21 100644 --- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp +++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp @@ -1028,6 +1028,9 @@ class DeclAndTypePrinter::Implementation /// annotations like \c strong and \c weak. bool isObjCReferenceCountableObjectType(Type ty) { if (auto classDecl = ty->getClassOrBoundGenericClass()) { + if (classDecl->isForeignReferenceType()) + return false; + switch (classDecl->getForeignClassKind()) { case ClassDecl::ForeignKind::Normal: case ClassDecl::ForeignKind::RuntimeOnly: diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 474f204bbd47b..723df268efd7e 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2599,6 +2599,8 @@ class CFunctionTypeConventions : public Conventions { return ResultConvention::Unowned; if (FnType->getExtInfo().getProducesResult()) return ResultConvention::Owned; + if (tl.getLoweredType().isForeignReferenceType()) + return ResultConvention::Unowned; return ResultConvention::Autoreleased; } @@ -3105,14 +3107,17 @@ CanSILFunctionType TypeConverter::getUncachedSILFunctionTypeForConstant( bridgedTypes); } -static bool isClassOrProtocolMethod(ValueDecl *vd) { +static bool isObjCMethod(ValueDecl *vd) { if (!vd->getDeclContext()) return false; + Type contextType = vd->getDeclContext()->getDeclaredInterfaceType(); if (!contextType) return false; - return contextType->getClassOrBoundGenericClass() - || contextType->isClassExistentialType(); + + bool isRefCountedClass = contextType->getClassOrBoundGenericClass() && + !contextType->isForeignReferenceType(); + return isRefCountedClass || contextType->isClassExistentialType(); } SILFunctionTypeRepresentation @@ -3123,7 +3128,7 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) { c.getDecl()->isImportAsMember()) return SILFunctionTypeRepresentation::CFunctionPointer; - if (isClassOrProtocolMethod(c.getDecl()) || + if (isObjCMethod(c.getDecl()) || c.kind == SILDeclRef::Kind::IVarInitializer || c.kind == SILDeclRef::Kind::IVarDestroyer) return SILFunctionTypeRepresentation::ObjCMethod; diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 5a603962fcaf7..d0d43aa2f64e4 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -51,6 +51,8 @@ namespace { /// Class metatypes have non-trivial representation due to the /// possibility of subclassing. bool visitClassType(CanClassType type) { + if (type->isForeignReferenceType()) + return true; return false; } bool visitBoundGenericClassType(CanBoundGenericClassType type) { @@ -1651,6 +1653,10 @@ namespace { TypeLowering *handleReference(CanType type, RecursiveProperties properties) { auto silType = SILType::getPrimitiveObjectType(type); + if (type.isForeignReferenceType()) + return new (TC) TrivialTypeLowering( + silType, RecursiveProperties::forTrivial(), Expansion); + return new (TC) ReferenceTypeLowering(silType, properties, Expansion); } diff --git a/lib/SIL/Utils/InstructionUtils.cpp b/lib/SIL/Utils/InstructionUtils.cpp index 1d61c18172481..4aa6bf9d54c8b 100644 --- a/lib/SIL/Utils/InstructionUtils.cpp +++ b/lib/SIL/Utils/InstructionUtils.cpp @@ -672,8 +672,10 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) if (auto selfType = instTy->getAs()) instTy = selfType->getSelfType(); auto *cl = instTy->getClassOrBoundGenericClass(); - if ((cl && (cl->usesObjCObjectModel() || cl->isForeign())) || - instTy->isAnyObject()) + bool isForeign = + cl->getObjectModel() == ReferenceCounting::ObjC || + cl->isForeign(); + if ((cl && isForeign) || instTy->isAnyObject()) return RuntimeEffect::MetaData | RuntimeEffect::ObjectiveC; return RuntimeEffect::MetaData; } @@ -690,7 +692,8 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) return RuntimeEffect::MetaData; case ExistentialRepresentation::Class: { auto *cl = opType.getClassOrBoundGenericClass(); - if ((cl && cl->usesObjCObjectModel()) || opType.isAnyObject()) + bool usesObjCModel = cl->getObjectModel() == ReferenceCounting::ObjC; + if ((cl && usesObjCModel) || opType.isAnyObject()) return RuntimeEffect::MetaData | RuntimeEffect::ObjectiveC; return RuntimeEffect::MetaData | RuntimeEffect::ObjectiveC; } diff --git a/lib/SIL/Utils/SILBridging.cpp b/lib/SIL/Utils/SILBridging.cpp index 62f6377cda323..73c55306ac060 100644 --- a/lib/SIL/Utils/SILBridging.cpp +++ b/lib/SIL/Utils/SILBridging.cpp @@ -49,7 +49,7 @@ ArrayRef swift::getSILValues(BridgedValueArray values, // words. The first word is the actual object. Pick the objects and store them // into storage. for (unsigned idx = 0; idx < values.count; ++idx) { - storage.push_back(castToSILValue({base[idx * 2]})); + storage.push_back(static_cast(base[idx * 2])); } return storage; } @@ -76,7 +76,7 @@ static void setUnimplementedRange(SwiftMetatype metatype, /// Registers the metatype of a libswift class. /// Called by initializeLibSwift(). void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype) { - nodeMetatypesInitialized = true; +// nodeMetatypesInitialized = true; // Handle the important non Node classes. StringRef clName = getStringRef(className); @@ -161,39 +161,39 @@ void freeBridgedStringRef(BridgedStringRef str) { // SILFunction //===----------------------------------------------------------------------===// -BridgedStringRef SILFunction_getName(BridgedFunction function) { - return getBridgedStringRef(castToFunction(function)->getName()); +BridgedStringRef SILFunction_getName(SILFunction *function) { + llvm::dbgs() << "Getting name: "; + llvm::dbgs() << function->getName() << "\n"; + return getBridgedStringRef(function->getName()); } -std::string SILFunction_debugDescription(BridgedFunction function) { +std::string SILFunction_debugDescription(SILFunction *function) { std::string str; llvm::raw_string_ostream os(str); - castToFunction(function)->print(os); + function->print(os); str.pop_back(); // Remove trailing newline. return str; } -OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function) { - SILFunction *f = castToFunction(function); +SILBasicBlock * _Nullable SILFunction_firstBlock(SILFunction *f) { if (f->empty()) - return {nullptr}; - return {f->getEntryBlock()}; + return nullptr; +// f->getEntryBlock()->dump(); + return &*f->begin(); } -OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function) { - SILFunction *f = castToFunction(function); +OptionalRef SILFunction_lastBlock(SILFunction *f) { if (f->empty()) - return {nullptr}; - return {&*f->rbegin()}; + return nullptr; + return &*f->rbegin(); } -SwiftInt SILFunction_numIndirectResultArguments(BridgedFunction function) { - return castToFunction(function)->getLoweredFunctionType()-> - getNumIndirectFormalResults(); +SwiftInt SILFunction_numIndirectResultArguments(SILFunction *function) { + return function->getLoweredFunctionType()->getNumIndirectFormalResults(); } -SwiftInt SILFunction_getSelfArgumentIndex(BridgedFunction function) { - CanSILFunctionType fTy = castToFunction(function)->getLoweredFunctionType(); +SwiftInt SILFunction_getSelfArgumentIndex(SILFunction *function) { + CanSILFunctionType fTy = function->getLoweredFunctionType(); if (!fTy->hasSelfParam()) return -1; return fTy->getNumParameters() + fTy->getNumIndirectFormalResults() - 1; @@ -206,58 +206,65 @@ SwiftInt SILFunction_getSelfArgumentIndex(BridgedFunction function) { static_assert(BridgedSuccessorSize == sizeof(SILSuccessor), "wrong bridged SILSuccessor size"); -OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block) { - SILBasicBlock *b = castToBasicBlock(block); +int SILBasicBlock_mytest(SILBasicBlock *b) { + llvm::dbgs() << "starting my test\n"; + auto iter = b->getIterator(); + while (iter != b->getParent()->end()) { + iter->dump(); + iter = std::next(iter); + llvm::dbgs() << "in my test\n"; + } + return 42; +} + +OptionalRef SILBasicBlock_next(SILBasicBlock *b) { auto iter = std::next(b->getIterator()); if (iter == b->getParent()->end()) - return {nullptr}; - return {&*iter}; + return nullptr; + return &*iter; } -OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block) { - SILBasicBlock *b = castToBasicBlock(block); +OptionalRef SILBasicBlock_previous(SILBasicBlock *b) { auto iter = std::next(b->getReverseIterator()); if (iter == b->getParent()->rend()) - return {nullptr}; - return {&*iter}; + return nullptr; + return &*iter; } -BridgedFunction SILBasicBlock_getFunction(BridgedBasicBlock block) { - return {castToBasicBlock(block)->getParent()}; +SILFunction *SILBasicBlock_getFunction(SILBasicBlock *block) { + return block->getParent(); } -std::string SILBasicBlock_debugDescription(BridgedBasicBlock block) { +std::string SILBasicBlock_debugDescription(SILBasicBlock *block) { std::string str; llvm::raw_string_ostream os(str); - castToBasicBlock(block)->print(os); + block->print(os); str.pop_back(); // Remove trailing newline. return str; } -OptionalBridgedInstruction SILBasicBlock_firstInst(BridgedBasicBlock block) { - SILBasicBlock *b = castToBasicBlock(block); +SILInstruction *SILBasicBlock_firstInst(SILBasicBlock *b) { if (b->empty()) - return {nullptr}; - return {b->front().asSILNode()}; + return nullptr; + return &b->front(); } -OptionalBridgedInstruction SILBasicBlock_lastInst(BridgedBasicBlock block) { - SILBasicBlock *b = castToBasicBlock(block); +OptionalRef SILBasicBlock_lastInst(SILBasicBlock *b) { if (b->empty()) - return {nullptr}; - return {b->back().asSILNode()}; + return nullptr; + return &b->back(); } -SwiftInt SILBasicBlock_getNumArguments(BridgedBasicBlock block) { - return castToBasicBlock(block)->getNumArguments(); +SwiftInt SILBasicBlock_getNumArguments(SILBasicBlock *block) { + return block->getNumArguments(); } -BridgedArgument SILBasicBlock_getArgument(BridgedBasicBlock block, SwiftInt index) { - return {castToBasicBlock(block)->getArgument(index)}; +SILArgument *SILBasicBlock_getArgument(SILBasicBlock *block, SwiftInt index) { + return block->getArgument(index); } -OptionalBridgedSuccessor SILBasicBlock_getFirstPred(BridgedBasicBlock block) { - return {castToBasicBlock(block)->pred_begin().getSuccessorRef()}; +OptionalBridgedSuccessor SILBasicBlock_getFirstPred(SILBasicBlock *block) { + return {block->pred_begin().getSuccessorRef()}; } static SILSuccessor *castToSuccessor(BridgedSuccessor succ) { @@ -268,20 +275,20 @@ OptionalBridgedSuccessor SILSuccessor_getNext(BridgedSuccessor succ) { return {castToSuccessor(succ)->getNext()}; } -BridgedBasicBlock SILSuccessor_getTargetBlock(BridgedSuccessor succ) { - return {castToSuccessor(succ)->getBB()}; +SILBasicBlock *SILSuccessor_getTargetBlock(BridgedSuccessor succ) { + return castToSuccessor(succ)->getBB(); } -BridgedInstruction SILSuccessor_getContainingInst(BridgedSuccessor succ) { - return {castToSuccessor(succ)->getContainingInst()}; +SILInstruction *SILSuccessor_getContainingInst(BridgedSuccessor succ) { + return castToSuccessor(succ)->getContainingInst(); } //===----------------------------------------------------------------------===// // SILArgument //===----------------------------------------------------------------------===// -BridgedBasicBlock SILArgument_getParent(BridgedArgument argument) { - return {static_cast(argument.obj)->getParent()}; +SILBasicBlock *SILArgument_getParent(SILArgument *argument) { + return argument->getParent(); } //===----------------------------------------------------------------------===// @@ -291,10 +298,19 @@ BridgedBasicBlock SILArgument_getParent(BridgedArgument argument) { static_assert(BridgedOperandSize == sizeof(Operand), "wrong bridged Operand size"); -std::string SILNode_debugDescription(BridgedNode node) { +std::string SILNode_debugDescription(ValueBase *node) { + std::string str; + llvm::raw_string_ostream os(str); + node->print(os); + str.pop_back(); // Remove trailing newline. + return str; +} + +std::string SILInstruction_debugDescription(SILInstruction *i) { + i->dump(); std::string str; llvm::raw_string_ostream os(str); - castToSILNode(node)->print(os); + i->print(os); str.pop_back(); // Remove trailing newline. return str; } @@ -303,7 +319,7 @@ static Operand *castToOperand(BridgedOperand operand) { return const_cast(static_cast(operand.op)); } -BridgedValue Operand_getValue(BridgedOperand operand) { +ValueBase *Operand_getValue(BridgedOperand operand) { return {castToOperand(operand)->get()}; } @@ -311,32 +327,32 @@ OptionalBridgedOperand Operand_nextUse(BridgedOperand operand) { return {castToOperand(operand)->getNextUse()}; } -BridgedInstruction Operand_getUser(BridgedOperand operand) { - return {castToOperand(operand)->getUser()->asSILNode()}; +SILInstruction *Operand_getUser(BridgedOperand operand) { + return castToOperand(operand)->getUser()->asSILNode()->castToInstruction(); } SwiftInt Operand_isTypeDependent(BridgedOperand operand) { return castToOperand(operand)->isTypeDependent() ? 1 : 0; } -OptionalBridgedOperand SILValue_firstUse(BridgedValue value) { - return {*castToSILValue(value)->use_begin()}; +OptionalBridgedOperand SILValue_firstUse(ValueBase *value) { + return {*value->use_begin()}; } -BridgedType SILValue_getType(BridgedValue value) { - return { castToSILValue(value)->getType().getOpaqueValue() }; +SILType SILValue_getType(ValueBase *value) { + return value->getType(); } //===----------------------------------------------------------------------===// // SILType //===----------------------------------------------------------------------===// -SwiftInt SILType_isAddress(BridgedType type) { - return castToSILType(type).isAddress(); +SwiftInt SILType_isAddress(SILType type) { + return type.isAddress(); } -SwiftInt SILType_isTrivial(BridgedType type, BridgedFunction function) { - return castToSILType(type).isTrivial(*castToFunction(function)); +SwiftInt SILType_isTrivial(SILType type, SILFunction *function) { + return type.isTrivial(*function); } //===----------------------------------------------------------------------===// @@ -359,62 +375,59 @@ std::string SILGlobalVariable_debugDescription(BridgedGlobalVar global) { // SILInstruction //===----------------------------------------------------------------------===// -OptionalBridgedInstruction SILInstruction_next(BridgedInstruction inst) { - SILInstruction *i = castToInst(inst); +OptionalRef SILInstruction_next(SILInstruction *i) { auto iter = std::next(i->getIterator()); if (iter == i->getParent()->end()) - return {nullptr}; - return {iter->asSILNode()}; + return nullptr; + return cast(iter->asSILNode()); } -OptionalBridgedInstruction SILInstruction_previous(BridgedInstruction inst) { - SILInstruction *i = castToInst(inst); +OptionalRef SILInstruction_previous(SILInstruction *i) { auto iter = std::next(i->getReverseIterator()); if (iter == i->getParent()->rend()) - return {nullptr}; - return {iter->asSILNode()}; + return nullptr; + return cast(iter->asSILNode()); } -BridgedBasicBlock SILInstruction_getParent(BridgedInstruction inst) { - SILInstruction *i = castToInst(inst); +SILBasicBlock *SILInstruction_getParent(SILInstruction *i) { assert(!i->isStaticInitializerInst() && "cannot get the parent of a static initializer instruction"); - return {i->getParent()}; + return i->getParent(); } -BridgedArrayRef SILInstruction_getOperands(BridgedInstruction inst) { - auto operands = castToInst(inst)->getAllOperands(); +BridgedArrayRef SILInstruction_getOperands(SILInstruction *inst) { + auto operands = inst->getAllOperands(); return {(const unsigned char *)operands.data(), operands.size()}; } -void SILInstruction_setOperand(BridgedInstruction inst, SwiftInt index, - BridgedValue value) { - castToInst(inst)->setOperand((unsigned)index, castToSILValue(value)); +void SILInstruction_setOperand(SILInstruction *inst, SwiftInt index, + ValueBase *value) { + inst->setOperand((unsigned)index, value); } -BridgedLocation SILInstruction_getLocation(BridgedInstruction inst) { - SILDebugLocation loc = castToInst(inst)->getDebugLocation(); +BridgedLocation SILInstruction_getLocation(SILInstruction *inst) { + SILDebugLocation loc = inst->getDebugLocation(); return *reinterpret_cast(&loc); } -BridgedMemoryBehavior SILInstruction_getMemBehavior(BridgedInstruction inst) { - return (BridgedMemoryBehavior)castToInst(inst)->getMemoryBehavior(); +BridgedMemoryBehavior SILInstruction_getMemBehavior(SILInstruction *inst) { + return (BridgedMemoryBehavior)inst->getMemoryBehavior(); } -BridgedInstruction MultiValueInstResult_getParent(BridgedMultiValueResult result) { +SILInstruction *MultiValueInstResult_getParent(BridgedMultiValueResult result) { return {static_cast(result.obj)->getParent()}; } -SwiftInt MultipleValueInstruction_getNumResults(BridgedInstruction inst) { - return castToInst(inst)->getNumResults(); +SwiftInt MultipleValueInstruction_getNumResults(MultipleValueInstruction *inst) { + return inst->getNumResults(); } BridgedMultiValueResult -MultipleValueInstruction_getResult(BridgedInstruction inst, SwiftInt index) { - return {castToInst(inst)->getResult(index)}; +MultipleValueInstruction_getResult(MultipleValueInstruction *inst, SwiftInt index) { + return {inst->getResult(index)}; } -BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term) { - auto successors = castToInst(term)->getSuccessors(); +BridgedArrayRef TermInst_getSuccessors(TermInst *term) { + auto successors = term->getSuccessors(); return {(const unsigned char *)successors.data(), successors.size()}; } @@ -422,72 +435,72 @@ BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term) { // Instruction classes //===----------------------------------------------------------------------===// -BridgedStringRef CondFailInst_getMessage(BridgedInstruction cfi) { - return getBridgedStringRef(castToInst(cfi)->getMessage()); +BridgedStringRef CondFailInst_getMessage(CondFailInst *cfi) { + return getBridgedStringRef(cfi->getMessage()); } -BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst) { - return {castToInst(globalInst)->getReferencedGlobal()}; +BridgedGlobalVar GlobalAccessInst_getGlobal(GlobalAccessInst *globalInst) { + return {globalInst->getReferencedGlobal()}; } -SwiftInt TupleExtractInst_fieldIndex(BridgedInstruction tei) { - return castToInst(tei)->getFieldIndex(); +SwiftInt TupleExtractInst_fieldIndex(TupleExtractInst *tei) { + return tei->getFieldIndex(); } -SwiftInt TupleElementAddrInst_fieldIndex(BridgedInstruction teai) { - return castToInst(teai)->getFieldIndex(); +SwiftInt TupleElementAddrInst_fieldIndex(TupleElementAddrInst *teai) { + return teai->getFieldIndex(); } -SwiftInt StructExtractInst_fieldIndex(BridgedInstruction sei) { - return castToInst(sei)->getFieldIndex(); +SwiftInt StructExtractInst_fieldIndex(StructExtractInst *sei) { + return sei->getFieldIndex(); } -SwiftInt StructElementAddrInst_fieldIndex(BridgedInstruction seai) { - return castToInst(seai)->getFieldIndex(); +SwiftInt StructElementAddrInst_fieldIndex(StructElementAddrInst *seai) { + return seai->getFieldIndex(); } -SwiftInt EnumInst_caseIndex(BridgedInstruction ei) { - return getCaseIndex(castToInst(ei)->getElement()); +SwiftInt EnumInst_caseIndex(EnumInst *ei) { + return getCaseIndex(ei->getElement()); } -SwiftInt UncheckedEnumDataInst_caseIndex(BridgedInstruction uedi) { - return getCaseIndex(castToInst(uedi)->getElement()); +SwiftInt UncheckedEnumDataInst_caseIndex(UncheckedEnumDataInst *uedi) { + return getCaseIndex(uedi->getElement()); } -SwiftInt RefElementAddrInst_fieldIndex(BridgedInstruction reai) { - return castToInst(reai)->getFieldIndex(); +SwiftInt RefElementAddrInst_fieldIndex(RefElementAddrInst *reai) { + return reai->getFieldIndex(); } -SwiftInt PartialApplyInst_numArguments(BridgedInstruction pai) { - return castToInst(pai)->getNumArguments(); +SwiftInt PartialApplyInst_numArguments(PartialApplyInst *pai) { + return pai->getNumArguments(); } -SwiftInt ApplyInst_numArguments(BridgedInstruction ai) { - return castToInst(ai)->getNumArguments(); +SwiftInt ApplyInst_numArguments(ApplyInst *ai) { + return ai->getNumArguments(); } -SwiftInt BeginApplyInst_numArguments(BridgedInstruction tai) { - return castToInst(tai)->getNumArguments(); +SwiftInt BeginApplyInst_numArguments(BeginApplyInst *tai) { + return tai->getNumArguments(); } -SwiftInt TryApplyInst_numArguments(BridgedInstruction tai) { - return castToInst(tai)->getNumArguments(); +SwiftInt TryApplyInst_numArguments(TryApplyInst *tai) { + return tai->getNumArguments(); } -BridgedBasicBlock BranchInst_getTargetBlock(BridgedInstruction bi) { - return {castToInst(bi)->getDestBB()}; +SILBasicBlock *BranchInst_getTargetBlock(BranchInst *bi) { + return bi->getDestBB(); } -SwiftInt SwitchEnumInst_getNumCases(BridgedInstruction se) { - return castToInst(se)->getNumCases(); +SwiftInt SwitchEnumInst_getNumCases(SwitchEnumInst *se) { + return se->getNumCases(); } -SwiftInt SwitchEnumInst_getCaseIndex(BridgedInstruction se, SwiftInt idx) { - return getCaseIndex(castToInst(se)->getCase(idx).first); +SwiftInt SwitchEnumInst_getCaseIndex(SwitchEnumInst *se, SwiftInt idx) { + return getCaseIndex(se->getCase(idx).first); } -SwiftInt StoreInst_getStoreOwnership(BridgedInstruction store) { - return (SwiftInt)castToInst(store)->getOwnershipQualifier(); +SwiftInt StoreInst_getStoreOwnership(StoreInst *store) { + return (SwiftInt)store->getOwnershipQualifier(); } @@ -495,21 +508,22 @@ SwiftInt StoreInst_getStoreOwnership(BridgedInstruction store) { // SILBuilder //===----------------------------------------------------------------------===// -BridgedInstruction SILBuilder_createBuiltinBinaryFunction( - BridgedInstruction insertionPoint, +SILInstruction *SILBuilder_createBuiltinBinaryFunction( + SILInstruction *insertionPoint, BridgedLocation loc, BridgedStringRef name, - BridgedType operandType, BridgedType resultType, + SILType operandType, SILType resultType, BridgedValueArray arguments) { - SILBuilder builder(castToInst(insertionPoint), getSILDebugScope(loc)); + SILBuilder builder(insertionPoint, getSILDebugScope(loc)); SmallVector argValues; return {builder.createBuiltinBinaryFunction(getRegularLocation(loc), - getStringRef(name), getSILType(operandType), getSILType(resultType), + getStringRef(name), operandType, resultType, getSILValues(arguments, argValues))}; } -BridgedInstruction SILBuilder_createCondFail(BridgedInstruction insertionPoint, - BridgedLocation loc, BridgedValue condition, BridgedStringRef messge) { - SILBuilder builder(castToInst(insertionPoint), getSILDebugScope(loc)); - return {builder.createCondFail(getRegularLocation(loc), - castToSILValue(condition), getStringRef(messge))}; +SILInstruction *SILBuilder_createCondFail( + SILInstruction *insertionPoint, BridgedLocation loc, + ValueBase *condition, BridgedStringRef messge) { + SILBuilder builder(insertionPoint, getSILDebugScope(loc)); + return {builder.createCondFail(getRegularLocation(loc), condition, + getStringRef(messge))}; } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 0c426b9fae316..432643461e4fe 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -821,8 +821,10 @@ class SILVerifier : public SILVerifierBase { // Require that the operand is a non-optional, non-unowned reference-counted // type. void requireReferenceValue(SILValue value, const Twine &valueDescription) { - require(value->getType().isObject(), valueDescription +" must be an object"); - require(value->getType().isReferenceCounted(F.getModule()), + require(value->getType().isObject(), + valueDescription + " must be an object"); + require(value->getType().isReferenceCounted(F.getModule()) || + value->getType().isForeignReferenceType(), valueDescription + " must have reference semantics"); forbidObjectType(UnownedStorageType, value, valueDescription); } @@ -3430,9 +3432,11 @@ class SILVerifier : public SILVerifierBase { "foreign method cannot be dispatched natively"); require(!isa(member.getDecl()->getDeclContext()), "extension method cannot be dispatched natively"); - - // The method ought to appear in the class vtable. - require(VerifyClassMethodVisitor(member).Seen, + + // The method ought to appear in the class vtable unless it's a foreign + // reference type. + require(VerifyClassMethodVisitor(member).Seen || + operandType.isForeignReferenceType(), "method does not appear in the class's vtable"); } diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index 959be60d01f5f..3f1125fad66d3 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -570,7 +570,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) { bool Lowering::usesObjCAllocator(ClassDecl *theClass) { // If the root class was implemented in Objective-C, use Objective-C's // allocation methods because they may have been overridden. - return theClass->usesObjCObjectModel(); + return theClass->getObjectModel() == ReferenceCounting::ObjC; } void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) { diff --git a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp index 2fe0c7ad2316d..53c5f878c3888 100644 --- a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp @@ -821,8 +821,8 @@ inline AliasAnalysis *castToAliasAnalysis(BridgedAliasAnalysis aa) { } BridgedMemoryBehavior AliasAnalysis_getMemBehavior(BridgedAliasAnalysis aa, - BridgedInstruction inst, - BridgedValue addr) { + SILInstruction *inst, + ValueBase *addr) { return (BridgedMemoryBehavior)castToAliasAnalysis(aa)-> - computeMemoryBehavior(castToInst(inst), castToSILValue(addr)); + computeMemoryBehavior(inst, addr); } diff --git a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp index 023237e4d7dd4..1b2c23e158d55 100644 --- a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp @@ -326,9 +326,9 @@ void BasicCalleeAnalysis::print(llvm::raw_ostream &os) const { //===----------------------------------------------------------------------===// BridgedCalleeList CalleeAnalysis_getCallees(BridgedCalleeAnalysis calleeAnalysis, - BridgedValue callee) { + ValueBase *callee) { BasicCalleeAnalysis *bca = static_cast(calleeAnalysis.bca); - CalleeList cl = bca->getCalleeListOfValue(castToSILValue(callee)); + CalleeList cl = bca->getCalleeListOfValue(callee); return {cl.getOpaquePtr(), cl.getOpaqueKind(), cl.isIncomplete()}; } @@ -338,11 +338,11 @@ SwiftInt BridgedFunctionArray_size(BridgedCalleeList callees) { return cl.end() - cl.begin(); } -BridgedFunction BridgedFunctionArray_get(BridgedCalleeList callees, - SwiftInt index) { +SILFunction *BridgedFunctionArray_get(BridgedCalleeList callees, + SwiftInt index) { CalleeList cl = CalleeList::fromOpaque(callees.opaquePtr, callees.kind, callees.incomplete); auto iter = cl.begin() + index; assert(index >= 0 && iter < cl.end()); - return {*iter}; + return *iter; } diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp index c746374951536..ddcd0d4fc701a 100644 --- a/lib/SILOptimizer/PassManager/PassManager.cpp +++ b/lib/SILOptimizer/PassManager/PassManager.cpp @@ -1173,8 +1173,8 @@ void PassContext_notifyChanges(BridgedPassContext passContext, } void PassContext_eraseInstruction(BridgedPassContext passContext, - BridgedInstruction inst) { - castToPassInvocation(passContext)->eraseInstruction(castToInst(inst)); + SILInstruction *inst) { + castToPassInvocation(passContext)->eraseInstruction(inst); } SwiftInt PassContext_isSwift51RuntimeAvailable(BridgedPassContext context) { diff --git a/lib/SILOptimizer/PassManager/Passes.cpp b/lib/SILOptimizer/PassManager/Passes.cpp index 338690f4536ca..38513d327ae52 100644 --- a/lib/SILOptimizer/PassManager/Passes.cpp +++ b/lib/SILOptimizer/PassManager/Passes.cpp @@ -236,10 +236,10 @@ static void runBridgedFunctionPass(BridgedFunctionPassRunFn &runFunction, return; } } - if (!f->isBridged()) { - llvm::errs() << "SILFunction metatype is not registered\n"; - abort(); - } +// if (!f->isBridged()) { +// llvm::errs() << "SILFunction metatype is not registered\n"; +// abort(); +// } runFunction({{f}, {passManager->getLibswiftPassInvocation()}}); } diff --git a/lib/SILOptimizer/SILCombiner/SILCombine.cpp b/lib/SILOptimizer/SILCombiner/SILCombine.cpp index aed8e91392f73..5c6c6de06439d 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombine.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombine.cpp @@ -472,7 +472,7 @@ void SILCombiner::eraseInstIncludingUsers(SILInstruction *inst) { void SILCombiner::runSwiftInstructionPass(SILInstruction *inst, void (*runFunction)(BridgedInstructionPassCtxt)) { Worklist.setLibswiftPassInvocation(&libswiftPassInvocation); - runFunction({ {inst->asSILNode()}, {&libswiftPassInvocation} }); + runFunction({inst, {&libswiftPassInvocation}}); Worklist.setLibswiftPassInvocation(nullptr); libswiftPassInvocation.finishedPassRun(); } @@ -528,7 +528,7 @@ namespace { class SILCombine : public SILFunctionTransform { llvm::SmallVector TrackingList; - + /// The entry point to the transformation. void run() override { auto *AA = PM->getAnalysis(getFunction()); diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 347fc05767163..ba0b65261da45 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -5828,6 +5828,10 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, type1, type2, locator); return getTypeMatchSuccess(); }; + + // Foreign reference types do *not* conform to AnyObject. + if (type1->isForeignReferenceType() && type2->isAnyObject()) + return getTypeMatchFailure(locator); if (auto meta1 = type1->getAs()) { if (meta1->getInstanceType()->mayHaveSuperclass() diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index d0236c0068ea9..c7f9961c67fc3 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -97,8 +97,12 @@ static bool contextAllowsPatternBindingWithoutVariables(DeclContext *dc) { } static bool hasStoredProperties(NominalTypeDecl *decl) { + bool isForeignReferenceTy = + isa(decl) && cast(decl)->isForeignReferenceType(); + return (isa(decl) || - (isa(decl) && !decl->hasClangNode())); + (isa(decl) && + (!decl->hasClangNode() || isForeignReferenceTy))); } static void computeLoweredStoredProperties(NominalTypeDecl *decl) { @@ -2226,6 +2230,9 @@ RequiresOpaqueAccessorsRequest::evaluate(Evaluator &evaluator, } else if (auto *structDecl = dyn_cast(dc)) { if (structDecl->hasClangNode()) return false; + } else if (isa(dc) && + cast(dc)->isForeignReferenceType()) { + return false; } // Stored properties in SIL mode don't get accessors. diff --git a/libswift/Sources/Optimizer/Analysis/AliasAnalysis.swift b/libswift/Sources/Optimizer/Analysis/AliasAnalysis.swift index d522038618a0f..6d97492a35999 100644 --- a/libswift/Sources/Optimizer/Analysis/AliasAnalysis.swift +++ b/libswift/Sources/Optimizer/Analysis/AliasAnalysis.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SILBridging import OptimizerBridging import SIL @@ -17,7 +18,7 @@ struct AliasAnalysis { let bridged: BridgedAliasAnalysis func mayRead(_ inst: Instruction, fromAddress: Value) -> Bool { - switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, fromAddress.bridged) { + switch AliasAnalysis_getMemBehavior(bridged, inst, fromAddress) { case MayReadBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true default: @@ -26,7 +27,7 @@ struct AliasAnalysis { } func mayWrite(_ inst: Instruction, toAddress: Value) -> Bool { - switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, toAddress.bridged) { + switch AliasAnalysis_getMemBehavior(bridged, inst, toAddress) { case MayWriteBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true default: @@ -35,7 +36,7 @@ struct AliasAnalysis { } func mayReadOrWrite(_ inst: Instruction, address: Value) -> Bool { - switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, address.bridged) { + switch AliasAnalysis_getMemBehavior(bridged, inst, address) { case MayReadBehavior, MayWriteBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true diff --git a/libswift/Sources/Optimizer/Analysis/CalleeAnalysis.swift b/libswift/Sources/Optimizer/Analysis/CalleeAnalysis.swift index 41ab03b5a450b..e14e26d15ef7a 100644 --- a/libswift/Sources/Optimizer/Analysis/CalleeAnalysis.swift +++ b/libswift/Sources/Optimizer/Analysis/CalleeAnalysis.swift @@ -10,14 +10,15 @@ // //===----------------------------------------------------------------------===// -import OptimizerBridging +import SILBridging import SIL +import OptimizerBridging public struct CalleeAnalysis { let bridged: BridgedCalleeAnalysis public func getCallees(callee: Value) -> FunctionArray { - return FunctionArray(bridged: CalleeAnalysis_getCallees(bridged, callee.bridged)) + return FunctionArray(bridged: CalleeAnalysis_getCallees(bridged, callee)) } } @@ -28,7 +29,7 @@ public struct FunctionArray : RandomAccessCollection, CustomReflectable { public var endIndex: Int { BridgedFunctionArray_size(bridged) } public subscript(_ index: Int) -> Function { - return BridgedFunctionArray_get(bridged, index).function + return BridgedFunctionArray_get(bridged, index) } public var allCalleesKnown: Bool { bridged.incomplete == 0 } diff --git a/libswift/Sources/Optimizer/FunctionPasses/MergeCondFails.swift b/libswift/Sources/Optimizer/FunctionPasses/MergeCondFails.swift index 33bf2fe37f430..a9eede069ea7a 100644 --- a/libswift/Sources/Optimizer/FunctionPasses/MergeCondFails.swift +++ b/libswift/Sources/Optimizer/FunctionPasses/MergeCondFails.swift @@ -10,15 +10,16 @@ // //===----------------------------------------------------------------------===// +import SILBridging import SIL let mergeCondFailsPass = FunctionPass(name: "merge-cond_fails", runMergeCondFails) /// Return true if the operand of the cond_fail instruction looks like /// the overflow bit of an arithmetic instruction. -private func hasOverflowConditionOperand(_ cfi: CondFailInst) -> Bool { - if let tei = cfi.operand as? TupleExtractInst { - return tei.operand is BuiltinInst +private func hasOverflowConditionOperand(_ cfi: swift.CondFailInst) -> Bool { + if let tei = getAsTupleExtractInst(cfi.operand) { + return isaBuiltinInst(tei.operand) } return false } @@ -30,15 +31,14 @@ private func hasOverflowConditionOperand(_ cfi: CondFailInst) -> Bool { /// This pass merges cond_fail instructions by building the disjunction of /// their operands. private func runMergeCondFails(function: Function, context: PassContext) { - // Merge cond_fail instructions if there is no side-effect or read in // between them. for block in function.blocks { // Per basic block list of cond_fails to merge. - var condFailToMerge = StackList(context) + var condFailToMerge = StackList(context) for inst in block.instructions { - if let cfi = inst as? CondFailInst { + if let cfi = getAsCondFailInst(inst) { // Do not process arithmetic overflow checks. We typically generate more // efficient code with separate jump-on-overflow. if !hasOverflowConditionOperand(cfi) && @@ -58,7 +58,7 @@ private func runMergeCondFails(function: Function, context: PassContext) { /// Try to merge the cond_fail instructions. Returns true if any could /// be merge. -private func mergeCondFails(_ condFailToMerge: inout StackList, +private func mergeCondFails(_ condFailToMerge: inout StackList, context: PassContext) { guard let lastCFI = condFailToMerge.last else { return @@ -70,10 +70,11 @@ private func mergeCondFails(_ condFailToMerge: inout StackList, // Merge conditions and remove the merged cond_fail instructions. for cfi in condFailToMerge { if let prevCond = mergedCond { - mergedCond = builder.createBuiltinBinaryFunction(name: "or", + let builtinCall = builder.createBuiltinBinaryFunction(name: "or", operandType: prevCond.type, resultType: prevCond.type, arguments: [prevCond, cfi.operand]) + mergedCond = getAsValue(builtinCall) didMerge = true } else { mergedCond = cfi.operand @@ -89,6 +90,6 @@ private func mergeCondFails(_ condFailToMerge: inout StackList, message: lastCFI.message) while let cfi = condFailToMerge.pop() { - context.erase(instruction: cfi) + context.erase(instruction: getAsSILInstruction(cfi)) } } diff --git a/libswift/Sources/Optimizer/FunctionPasses/SILPrinter.swift b/libswift/Sources/Optimizer/FunctionPasses/SILPrinter.swift index 2e15e24c443c1..8c6ef1e3e0c14 100644 --- a/libswift/Sources/Optimizer/FunctionPasses/SILPrinter.swift +++ b/libswift/Sources/Optimizer/FunctionPasses/SILPrinter.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SILBridging import SIL let silPrinterPass = FunctionPass(name: "sil-printer", runSILPrinter) @@ -18,6 +19,8 @@ func runSILPrinter(function: Function, context: PassContext) { print("run SILPrinter on function: \(function.name)") for (bbIdx, block) in function.blocks.enumerated() { + print("MARK - ") + print("bb\(bbIdx):") print(" predecessors: " + @@ -28,7 +31,7 @@ func runSILPrinter(function: Function, context: PassContext) { print(" arguments:") for arg in block.arguments { print(" arg: \(arg)") - for use in arg.uses { + for use in getAsValue(arg)!.uses { print(" user: \(use.instruction)") } } diff --git a/libswift/Sources/Optimizer/InstructionPasses/SimplifyGlobalValue.swift b/libswift/Sources/Optimizer/InstructionPasses/SimplifyGlobalValue.swift index e644a84f1e761..daa0299297f4c 100644 --- a/libswift/Sources/Optimizer/InstructionPasses/SimplifyGlobalValue.swift +++ b/libswift/Sources/Optimizer/InstructionPasses/SimplifyGlobalValue.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SILBridging import SIL // Removes all reference counting instructions of a `global_value` instruction @@ -18,12 +19,14 @@ import SIL // Note that `simplifyStrongRetainPass` and `simplifyStrongReleasePass` can // even remove "unbalanced" retains/releases of a `global_value`, but this // requires a minimum deployment target. -let simplifyGlobalValuePass = InstructionPass( +let simplifyGlobalValuePass = InstructionPass( name: "simplify-global_value", { - (globalValue: GlobalValueInst, context: PassContext) in + (inst: Instruction, context: PassContext) in + + let globalValue = getAsGlobalValueInst(inst)! var users = StackList(context) - if checkUsers(of: globalValue, users: &users) { + if checkUsers(of: getAsValue(globalValue)!, users: &users) { while let inst = users.pop() { context.erase(instruction: inst) } @@ -37,19 +40,19 @@ let simplifyGlobalValuePass = InstructionPass( private func checkUsers(of val: Value, users: inout StackList) -> Bool { for use in val.uses { let user = use.instruction - if user is RefCountingInst || user is DebugValueInst { + if user is RefCountingInst || isaDebugValueInst(user) { users.push(user) continue } - if let upCast = user as? UpcastInst { - if !checkUsers(of: upCast, users: &users) { + if let upCast = getAsUpcastInst(user) { + if !checkUsers(of: getAsValue(upCast)!, users: &users) { return false } continue } // Projection instructions don't access the object header, so they don't // prevent deleting reference counting instructions. - if user is RefElementAddrInst || user is RefTailAddrInst { + if isaRefElementAddrInst(user) || isaRefTailAddrInst(user) { continue } return false diff --git a/libswift/Sources/Optimizer/InstructionPasses/SimplifyStrongRetainRelease.swift b/libswift/Sources/Optimizer/InstructionPasses/SimplifyStrongRetainRelease.swift index b9cd4b78bc39b..f5ada37f8c0b4 100644 --- a/libswift/Sources/Optimizer/InstructionPasses/SimplifyStrongRetainRelease.swift +++ b/libswift/Sources/Optimizer/InstructionPasses/SimplifyStrongRetainRelease.swift @@ -10,14 +10,17 @@ // //===----------------------------------------------------------------------===// +import SILBridging import SIL -let simplifyStrongRetainPass = InstructionPass( +let simplifyStrongRetainPass = InstructionPass( name: "simplify-strong_retain", { - (retain: StrongRetainInst, context: PassContext) in + (inst: Instruction, context: PassContext) in + + let retain = getAsStrongRetainInst(inst)! if isNotReferenceCounted(value: retain.operand, context: context) { - context.erase(instruction: retain) + context.erase(instruction: getAsSILInstruction(retain)) return } @@ -35,32 +38,33 @@ let simplifyStrongRetainPass = InstructionPass( // it). But that does not mean that we cannot eliminate this pair with a // peephole. if let prev = retain.previous { - if let release = prev as? StrongReleaseInst { + if let release = getAsStrongReleaseInst(prev) { if release.operand == retain.operand { - context.erase(instruction: retain) - context.erase(instruction: release) + context.erase(instruction: getAsSILInstruction(retain)) + context.erase(instruction: getAsSILInstruction(release)) return } } } }) -let simplifyStrongReleasePass = InstructionPass( +let simplifyStrongReleasePass = InstructionPass( name: "simplify-strong_release", { - (release: StrongReleaseInst, context: PassContext) in + (inst: Instruction, context: PassContext) in + let release = getAsStrongReleaseInst(inst)! let op = release.operand if isNotReferenceCounted(value: op, context: context) { - context.erase(instruction: release) + context.erase(instruction: getAsSILInstruction(release)) return } // Release of a classbound existential converted from a class is just a // release of the class, squish the conversion. - if let ier = op as? InitExistentialRefInst { - if ier.uses.isSingleUse { - context.setOperand(of: release, at: 0, to: ier.operand) - context.erase(instruction: ier) + if let ier = getAsInitExistentialRefInst(op) { + if getAsValue(ier)!.uses.isSingleUse { + context.setOperand(of: getAsSILInstruction(release), at: 0, to: ier.operand) + context.erase(instruction: getAsSILInstruction(ier)) return } } @@ -69,46 +73,44 @@ let simplifyStrongReleasePass = InstructionPass( /// Returns true if \p value is something where reference counting instructions /// don't have any effect. private func isNotReferenceCounted(value: Value, context: PassContext) -> Bool { - switch value { - case let cfi as ConvertFunctionInst: - return isNotReferenceCounted(value: cfi.operand, context: context) - case let uci as UpcastInst: - return isNotReferenceCounted(value: uci.operand, context: context) - case let urc as UncheckedRefCastInst: - return isNotReferenceCounted(value: urc.operand, context: context) - case is GlobalValueInst: - // Since Swift 5.1, statically allocated objects have "immortal" reference - // counts. Therefore we can safely eliminate unbalaced retains and - // releases, because they are no-ops on immortal objects. - // Note that the `simplifyGlobalValuePass` pass is deleting balanced - // retains/releases, which doesn't require a Swift 5.1 minimum deployment - // targert. - return context.isSwift51RuntimeAvailable - case let rptr as RawPointerToRefInst: - // Like `global_value` but for the empty collection singletons from the - // stdlib, e.g. the empty Array singleton. - if context.isSwift51RuntimeAvailable { - // The pattern generated for empty collection singletons is: - // %0 = global_addr @_swiftEmptyArrayStorage - // %1 = address_to_pointer %0 - // %2 = raw_pointer_to_ref %1 - if let atp = rptr.operand as? AddressToPointerInst { - return atp.operand is GlobalAddrInst - } + if let cfi = getAsConvertFunctionInst(value) { + return isNotReferenceCounted(value: cfi.operand, context: context) + } else if let uci = getAsUpcastInst(value) { + return isNotReferenceCounted(value: uci.operand, context: context) + } else if let urc = getAsUncheckedRefCastInst(value) { + return isNotReferenceCounted(value: urc.operand, context: context) + } else if let rptr = getAsRawPointerToRefInst(value) { + // Like `global_value` but for the empty collection singletons from the + // stdlib, e.g. the empty Array singleton. + if context.isSwift51RuntimeAvailable { + // The pattern generated for empty collection singletons is: + // %0 = global_addr @_swiftEmptyArrayStorage + // %1 = address_to_pointer %0 + // %2 = raw_pointer_to_ref %1 + if let atp = getAsAddressToPointerInst(rptr.operand) { + return isaGlobalAddrInst(atp.operand) } - return false - case // Thin functions are not reference counted. - is ThinToThickFunctionInst, - // The same for meta types. - is ObjCExistentialMetatypeToObjectInst, - is ObjCMetatypeToObjectInst, - // Retain and Release of tagged strings is a no-op. - // The builtin code pattern to find tagged strings is: - // builtin "stringObjectOr_Int64" (or to tag the string) - // value_to_bridge_object (cast the UInt to bridge object) - is ValueToBridgeObjectInst: - return true - default: - return false + } + return false + } else if isaGlobalValueInst(value) { + // Since Swift 5.1, statically allocated objects have "immortal" reference + // counts. Therefore we can safely eliminate unbalaced retains and + // releases, because they are no-ops on immortal objects. + // Note that the `simplifyGlobalValuePass` pass is deleting balanced + // retains/releases, which doesn't require a Swift 5.1 minimum deployment + // targert. + return context.isSwift51RuntimeAvailable + } else if // Thin functions are not reference counted. + isaThinToThickFunctionInst(value) || + // The same for meta types. + isaObjCExistentialMetatypeToObjectInst(value) || + isaObjCMetatypeToObjectInst(value) || + // Retain and Release of tagged strings is a no-op. + // The builtin code pattern to find tagged strings is: + // builtin "stringObjectOr_Int64" (or to tag the string) + // value_to_bridge_object (cast the UInt to bridge object) + isaValueToBridgeObjectInst(value) { + return true } + return false } diff --git a/libswift/Sources/Optimizer/PassManager/PassRegistration.swift b/libswift/Sources/Optimizer/PassManager/PassRegistration.swift index 74f23d37e03e4..8950c9b56e7c7 100644 --- a/libswift/Sources/Optimizer/PassManager/PassRegistration.swift +++ b/libswift/Sources/Optimizer/PassManager/PassRegistration.swift @@ -29,8 +29,8 @@ private func registerPass( } } -private func registerPass( - _ pass: InstructionPass, +private func registerPass( + _ pass: InstructionPass, _ runFn: @escaping (@convention(c) (BridgedInstructionPassCtxt) -> ())) { pass.name.withBridgedStringRef { nameStr in SILCombine_registerInstructionPass(nameStr, runFn) diff --git a/libswift/Sources/Optimizer/PassManager/PassUtils.swift b/libswift/Sources/Optimizer/PassManager/PassUtils.swift index c1ad65a37d08d..404f8ff44e7ae 100644 --- a/libswift/Sources/Optimizer/PassManager/PassUtils.swift +++ b/libswift/Sources/Optimizer/PassManager/PassUtils.swift @@ -40,12 +40,12 @@ struct PassContext { if instruction is FullApplySite { PassContext_notifyChanges(passContext, callsChanged) } - if instruction is TermInst { + if getAsTermInst(instruction) != nil { PassContext_notifyChanges(passContext, branchesChanged) } PassContext_notifyChanges(passContext, instructionsChanged) - PassContext_eraseInstruction(passContext, instruction.bridged) + PassContext_eraseInstruction(passContext, instruction) } func setOperand(of instruction: Instruction, at index : Int, to value: Value) { @@ -54,7 +54,7 @@ struct PassContext { } PassContext_notifyChanges(passContext, instructionsChanged) - SILInstruction_setOperand(instruction.bridged, index, value.bridged) + SILInstruction_setOperand(instruction, index, value) } } @@ -70,25 +70,26 @@ struct FunctionPass { } func run(_ bridgedCtxt: BridgedFunctionPassCtxt) { - let function = bridgedCtxt.function.function + let function = bridgedCtxt.function let context = PassContext(passContext: bridgedCtxt.passContext) runFunction(function, context) } } -struct InstructionPass { +struct InstructionPass { let name: String - let runFunction: (InstType, PassContext) -> () + let runFunction: (Instruction, PassContext) -> () public init(name: String, - _ runFunction: @escaping (InstType, PassContext) -> ()) { + _ runFunction: @escaping (Instruction, PassContext) -> ()) { self.name = name self.runFunction = runFunction } func run(_ bridgedCtxt: BridgedInstructionPassCtxt) { - let inst = bridgedCtxt.instruction.getAs(InstType.self) + // TODO: this just needs to be a bridged cast function. + let inst = bridgedCtxt.instruction let context = PassContext(passContext: bridgedCtxt.passContext) runFunction(inst, context) } diff --git a/libswift/Sources/SIL/Argument.swift b/libswift/Sources/SIL/Argument.swift index 8c059353213d8..d2740424cbf49 100644 --- a/libswift/Sources/SIL/Argument.swift +++ b/libswift/Sources/SIL/Argument.swift @@ -12,35 +12,36 @@ import SILBridging +public typealias Argument = swift.SILArgument + /// A basic block argument. /// /// Maps to both, SILPhiArgument and SILFunctionArgument. -public class Argument : Value, Equatable { - public var definingInstruction: Instruction? { nil } - +extension swift.SILArgument { public var block: BasicBlock { - return SILArgument_getParent(bridged).block + return SILArgument_getParent(self) } - - var bridged: BridgedArgument { BridgedArgument(obj: SwiftObject(self)) } - public var index: Int { - return block.arguments.firstIndex(of: self)! - } - - public static func ==(lhs: Argument, rhs: Argument) -> Bool { - lhs === rhs - } + public var index: Int { Int(getIndex()) } } -final public class FunctionArgument : Argument { +public func ==(lhs: Argument, rhs: Argument) -> Bool { + isPtrEq(getAsValue(lhs)!, getAsValue(rhs)!) } -final public class BlockArgument : Argument { +public typealias FunctionArgument = swift.SILFunctionArgument; +public typealias BlockArgument = swift.SILPhiArgument; +extension BlockArgument { + public var block: BasicBlock { + return SILArgument_getParent(getAsSILArgument(self)!) + } + + public var index: Int { getAsSILArgument(self)!.index } + /// Note: critical edges are not supported, i.e. this is false if there is /// a cond_br in the predecessors. public var isPhiArgument: Bool { - block.predecessors.allSatisfy { $0.terminator is BranchInst } + block.predecessors.allSatisfy { isaBranchInst(getAsSILInstruction($0.terminator)) } } public var incomingPhiOperands: LazyMapSequence { @@ -55,10 +56,3 @@ final public class BlockArgument : Argument { return block.predecessors.lazy.map { $0.terminator.operands[idx].value } } } - -// Bridging utilities - -extension BridgedArgument { - var argument: Argument { obj.getAs(Argument.self) } - var functionArgument: FunctionArgument { obj.getAs(FunctionArgument.self) } -} diff --git a/libswift/Sources/SIL/BasicBlock.swift b/libswift/Sources/SIL/BasicBlock.swift index 4daea88fb85ab..1c39ec8d96606 100644 --- a/libswift/Sources/SIL/BasicBlock.swift +++ b/libswift/Sources/SIL/BasicBlock.swift @@ -12,35 +12,35 @@ import SILBridging -final public class BasicBlock : ListNode, CustomStringConvertible { - public var next: BasicBlock? { SILBasicBlock_next(bridged).block } - public var previous: BasicBlock? { SILBasicBlock_previous(bridged).block } +extension swift.SILBasicBlock : ListNode, CustomStringConvertible { + public var next: BasicBlock? { SILBasicBlock_next(self) } + public var previous: BasicBlock? { SILBasicBlock_previous(self) } - public var function: Function { SILBasicBlock_getFunction(bridged).function } + public var function: Function { SILBasicBlock_getFunction(self) } public var description: String { - var s = SILBasicBlock_debugDescription(bridged) + var s = SILBasicBlock_debugDescription(self) return String(cString: s.c_str()) } public var arguments: ArgumentArray { ArgumentArray(block: self) } public var instructions: List { - List(startAt: SILBasicBlock_firstInst(bridged).instruction) + List(startAt: SILBasicBlock_firstInst(self)) } public var reverseInstructions: ReverseList { - ReverseList(startAt: SILBasicBlock_lastInst(bridged).instruction) + ReverseList(startAt: SILBasicBlock_lastInst(self)) } - - public var terminator: TermInst { - SILBasicBlock_lastInst(bridged).instruction as! TermInst + + public var terminator: swift.TermInst { + getAsTermInst(SILBasicBlock_lastInst(self)!)! } public var successors: SuccessorArray { terminator.successors } public var predecessors: PredecessorList { - PredecessorList(startAt: SILBasicBlock_getFirstPred(bridged)) + PredecessorList(startAt: SILBasicBlock_getFirstPred(self)) } public var singlePredecessor: BasicBlock? { @@ -63,21 +63,21 @@ final public class BasicBlock : ListNode, CustomStringConvertible { } public var label: String { "bb\(index)" } - - var bridged: BridgedBasicBlock { BridgedBasicBlock(obj: SwiftObject(self)) } } -public func == (lhs: BasicBlock, rhs: BasicBlock) -> Bool { lhs === rhs } -public func != (lhs: BasicBlock, rhs: BasicBlock) -> Bool { lhs !== rhs } +public func == (lhs: BasicBlock, rhs: BasicBlock) -> Bool { isPtrEq(lhs, rhs) } +public func != (lhs: BasicBlock, rhs: BasicBlock) -> Bool { !(lhs == rhs) } + +public typealias BasicBlock = swift.SILBasicBlock public struct ArgumentArray : RandomAccessCollection { fileprivate let block: BasicBlock public var startIndex: Int { return 0 } - public var endIndex: Int { SILBasicBlock_getNumArguments(block.bridged) } + public var endIndex: Int { SILBasicBlock_getNumArguments(block) } public subscript(_ index: Int) -> Argument { - SILBasicBlock_getArgument(block.bridged, index).argument + SILBasicBlock_getArgument(block, index) } } @@ -94,7 +94,7 @@ public struct SuccessorArray : RandomAccessCollection, CustomReflectable { public subscript(_ index: Int) -> BasicBlock { precondition(index >= 0 && index < endIndex) let s = BridgedSuccessor(succ: succArray.data + index &* BridgedSuccessorSize); - return SILSuccessor_getTargetBlock(s).block + return SILSuccessor_getTargetBlock(s) } public var customMirror: Mirror { @@ -112,7 +112,7 @@ public struct PredecessorList : Sequence, IteratorProtocol, CustomReflectable { if let succPtr = currentSucc.succ { let succ = BridgedSuccessor(succ: succPtr) currentSucc = SILSuccessor_getNext(succ) - return SILSuccessor_getContainingInst(succ).instruction.block + return SILSuccessor_getContainingInst(succ).block } return nil } @@ -122,14 +122,3 @@ public struct PredecessorList : Sequence, IteratorProtocol, CustomReflectable { return Mirror(self, children: c) } } - - -// Bridging utilities - -extension BridgedBasicBlock { - var block: BasicBlock { obj.getAs(BasicBlock.self) } -} - -extension OptionalBridgedBasicBlock { - var block: BasicBlock? { obj.getAs(BasicBlock.self) } -} diff --git a/libswift/Sources/SIL/Builder.swift b/libswift/Sources/SIL/Builder.swift index a19423b515cbc..df402a4535a6c 100644 --- a/libswift/Sources/SIL/Builder.swift +++ b/libswift/Sources/SIL/Builder.swift @@ -18,7 +18,7 @@ public struct Builder { let location: Location private let passContext: BridgedPassContext - private var bridgedInsPoint: BridgedInstruction { insertionPoint.bridged } + private var bridgedInsPoint: swift.SILInstruction { insertionPoint } private func notifyInstructionsChanged() { PassContext_notifyChanges(passContext, instructionsChanged) @@ -40,24 +40,24 @@ public struct Builder { } public func createBuiltinBinaryFunction(name: String, - operandType: Type, resultType: Type, arguments: [Value]) -> BuiltinInst { + operandType: Type, resultType: Type, arguments: [Value]) -> swift.BuiltinInst { notifyInstructionsChanged() return arguments.withBridgedValues { valuesRef in return name.withBridgedStringRef { nameStr in let bi = SILBuilder_createBuiltinBinaryFunction( bridgedInsPoint, location.bridgedLocation, nameStr, - operandType.bridged, resultType.bridged, valuesRef) - return bi.getAs(BuiltinInst.self) + operandType, resultType, valuesRef) + return getAsBuiltinInst(bi)! } } } - public func createCondFail(condition: Value, message: String) -> CondFailInst { + public func createCondFail(condition: Value, message: String) -> swift.CondFailInst { notifyInstructionsChanged() return message.withBridgedStringRef { messageStr in let cf = SILBuilder_createCondFail( - bridgedInsPoint, location.bridgedLocation, condition.bridged, messageStr) - return cf.getAs(CondFailInst.self) + bridgedInsPoint, location.bridgedLocation, condition, messageStr) + return getAsCondFailInst(cf)! } } } diff --git a/libswift/Sources/SIL/Function.swift b/libswift/Sources/SIL/Function.swift index 9f2495f1f092d..615b550082010 100644 --- a/libswift/Sources/SIL/Function.swift +++ b/libswift/Sources/SIL/Function.swift @@ -12,51 +12,39 @@ import SILBridging -final public class Function : CustomStringConvertible { +public typealias Function = swift.SILFunction + +extension Function : CustomStringConvertible { public var name: String { - return SILFunction_getName(bridged).string + return SILFunction_getName(self).string } final public var description: String { - var s = SILFunction_debugDescription(bridged) + var s = SILFunction_debugDescription(self) return String(cString: s.c_str()) } - public var entryBlock: BasicBlock { - SILFunction_firstBlock(bridged).block! - } + public var entryBlock: BasicBlock { SILFunction_firstBlock(self)! } public var blocks : List { - return List(startAt: SILFunction_firstBlock(bridged).block) - } - - public var reverseBlocks : ReverseList { - return ReverseList(startAt: SILFunction_lastBlock(bridged).block) + return List(startAt: entryBlock) } public var arguments: LazyMapSequence { - entryBlock.arguments.lazy.map { $0 as! FunctionArgument } + entryBlock.arguments.lazy.map { getAsSILFunctionArgument(getAsValue($0))! } } public var numIndirectResultArguments: Int { - SILFunction_numIndirectResultArguments(bridged) + SILFunction_numIndirectResultArguments(self) } public var hasSelfArgument: Bool { - SILFunction_getSelfArgumentIndex(bridged) >= 0 + SILFunction_getSelfArgumentIndex(self) >= 0 } public var selfArgumentIndex: Int { - let selfIdx = SILFunction_getSelfArgumentIndex(bridged) + let selfIdx = SILFunction_getSelfArgumentIndex(self) assert(selfIdx >= 0) return selfIdx } - - public var bridged: BridgedFunction { BridgedFunction(obj: SwiftObject(self)) } -} - -// Bridging utilities - -extension BridgedFunction { - public var function: Function { obj.getAs(Function.self) } } diff --git a/libswift/Sources/SIL/GlobalVariable.swift b/libswift/Sources/SIL/GlobalVariable.swift index 3be05aec3d5af..eefa8bc1d7612 100644 --- a/libswift/Sources/SIL/GlobalVariable.swift +++ b/libswift/Sources/SIL/GlobalVariable.swift @@ -12,6 +12,7 @@ import SILBridging +// TODO: replace this with an extension on swift.SILGlobalVariable. final public class GlobalVariable : CustomStringConvertible { public var name: String { return SILGlobalVariable_getName(bridged).string diff --git a/libswift/Sources/SIL/Instruction.swift b/libswift/Sources/SIL/Instruction.swift index 718da8d7ba9f5..75f9735f1f974 100644 --- a/libswift/Sources/SIL/Instruction.swift +++ b/libswift/Sources/SIL/Instruction.swift @@ -16,30 +16,27 @@ import SILBridging // Instruction base classes //===----------------------------------------------------------------------===// -public class Instruction : ListNode, CustomStringConvertible, Hashable { - final public var next: Instruction? { - SILInstruction_next(bridged).instruction - } +public typealias Instruction = swift.SILInstruction - final public var previous: Instruction? { - SILInstruction_previous(bridged).instruction - } +extension swift.SILInstruction : ListNode, CustomStringConvertible { + final public var next: Instruction? { SILInstruction_next(self) } + + final public var previous: Instruction? { SILInstruction_previous(self) } final public var block: BasicBlock { - SILInstruction_getParent(bridged).block + SILInstruction_getParent(self) } final public var description: String { - var s = SILNode_debugDescription(bridgedNode) + var s = SILInstruction_debugDescription(self) return String(cString: s.c_str()) } final public var operands: OperandArray { - return OperandArray(opArray: SILInstruction_getOperands(bridged)) + return OperandArray(opArray: SILInstruction_getOperands(self)) } - fileprivate var resultCount: Int { 0 } - fileprivate func getResult(index: Int) -> Value { fatalError() } + fileprivate var resultCount: Int { Int(getNumResults()) } public struct Results : RandomAccessCollection { fileprivate let inst: Instruction @@ -47,7 +44,7 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable { public var startIndex: Int { 0 } public var endIndex: Int { numResults } - public subscript(_ index: Int) -> Value { inst.getResult(index: index) } + public subscript(_ index: Int) -> Value { getAsValue(inst.getResult(UInt32(index)))! } } final public var results: Results { @@ -55,17 +52,15 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable { } final public var location: Location { - return Location(bridgedLocation: SILInstruction_getLocation(bridged)) + return Location(bridgedLocation: SILInstruction_getLocation(self)) } - public var mayTrap: Bool { false } - final public var mayHaveSideEffects: Bool { - return mayTrap || mayWriteToMemory + return mayTrap() || mayWriteToMemory } final public var mayReadFromMemory: Bool { - switch SILInstruction_getMemBehavior(bridged) { + switch SILInstruction_getMemBehavior(self) { case MayReadBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true default: @@ -74,7 +69,7 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable { } final public var mayWriteToMemory: Bool { - switch SILInstruction_getMemBehavior(bridged) { + switch SILInstruction_getMemBehavior(self) { case MayWriteBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true default: @@ -83,7 +78,7 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable { } final public var mayReadOrWriteMemory: Bool { - switch SILInstruction_getMemBehavior(bridged) { + switch SILInstruction_getMemBehavior(self) { case MayReadBehavior, MayWriteBehavior, MayReadWriteBehavior, MayHaveSideEffectsBehavior: return true @@ -91,68 +86,6 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable { return false } } - - public static func ==(lhs: Instruction, rhs: Instruction) -> Bool { - lhs === rhs - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(ObjectIdentifier(self)) - } - - public var bridged: BridgedInstruction { - BridgedInstruction(obj: SwiftObject(self)) - } - var bridgedNode: BridgedNode { BridgedNode(obj: SwiftObject(self)) } -} - -extension BridgedInstruction { - public var instruction: Instruction { obj.getAs(Instruction.self) } - public func getAs(_ instType: T.Type) -> T { obj.getAs(T.self) } -} - -extension OptionalBridgedInstruction { - var instruction: Instruction? { obj.getAs(Instruction.self) } -} - -public class SingleValueInstruction : Instruction, Value { - final public var definingInstruction: Instruction? { self } - - fileprivate final override var resultCount: Int { 1 } - fileprivate final override func getResult(index: Int) -> Value { self } -} - -public final class MultipleValueInstructionResult : Value { - final public var description: String { - var s = SILNode_debugDescription(bridgedNode) - return String(cString: s.c_str()) - } - - public var instruction: Instruction { - MultiValueInstResult_getParent(bridged).instruction - } - - public var definingInstruction: Instruction? { instruction } - - var bridged: BridgedMultiValueResult { - BridgedMultiValueResult(obj: SwiftObject(self)) - } - var bridgedNode: BridgedNode { BridgedNode(obj: SwiftObject(self)) } -} - -extension BridgedMultiValueResult { - var result: MultipleValueInstructionResult { - obj.getAs(MultipleValueInstructionResult.self) - } -} - -public class MultipleValueInstruction : Instruction { - fileprivate final override var resultCount: Int { - return MultipleValueInstruction_getNumResults(bridged) - } - fileprivate final override func getResult(index: Int) -> Value { - MultipleValueInstruction_getResult(bridged, index).result - } } /// Instructions, which have a single operand. @@ -169,12 +102,11 @@ extension UnaryInstruction { // no-value instructions //===----------------------------------------------------------------------===// -/// Used for all non-value instructions which are not implemented here, yet. -/// See registerBridgedClass() in SILBridgingUtils.cpp. -final public class UnimplementedInstruction : Instruction { -} +extension swift.StoreInst { + final public var operands: OperandArray { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self))) + } -final public class StoreInst : Instruction { public var sourceOperand: Operand { return operands[0] } public var destinationOperand: Operand { return operands[1] } public var source: Value { return sourceOperand.value } @@ -185,289 +117,161 @@ final public class StoreInst : Instruction { case unqualified = 0, initialize = 1, assign = 2, trivial = 3 } public var destinationOwnership: StoreOwnership { - StoreOwnership(rawValue: StoreInst_getStoreOwnership(bridged))! + StoreOwnership(rawValue: StoreInst_getStoreOwnership(self))! } } -final public class CopyAddrInst : Instruction { +extension swift.CopyAddrInst { + final public var operands: OperandArray { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self))) + } + public var sourceOperand: Operand { return operands[0] } public var destinationOperand: Operand { return operands[1] } public var source: Value { return sourceOperand.value } public var destination: Value { return destinationOperand.value } } -final public class EndAccessInst : Instruction, UnaryInstruction { - public var beginAccess: BeginAccessInst { - return operand as! BeginAccessInst +extension swift.EndAccessInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value } -} - -final public class EndBorrowInst : Instruction, UnaryInstruction {} - -final public class DeallocStackInst : Instruction, UnaryInstruction { - public var allocstack: AllocStackInst { - return operand as! AllocStackInst + + public var beginAccess: swift.BeginAccessInst { + return getAsBeginAccessInst(operand)! } } -final public class CondFailInst : Instruction, UnaryInstruction { - public override var mayTrap: Bool { true } - - public var message: String { CondFailInst_getMessage(bridged).string } -} - -final public class FixLifetimeInst : Instruction, UnaryInstruction {} +extension swift.EndBorrowInst {} -final public class DebugValueInst : Instruction, UnaryInstruction {} +extension swift.CondFailInst { + public var message: String { CondFailInst_getMessage(self).string } + + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } + + final public var location: Location { + return Location(bridgedLocation: SILInstruction_getLocation(getAsSILInstruction(self))) + } + + final public var next: Instruction? { SILInstruction_next(getAsSILInstruction(self)) } -final public class UnconditionalCheckedCastAddrInst : Instruction { - public override var mayTrap: Bool { true } + final public var previous: Instruction? { SILInstruction_previous(getAsSILInstruction(self)) } } -final public class SetDeallocatingInst : Instruction, UnaryInstruction {} +extension swift.UnconditionalCheckedCastAddrInst {} -final public class DeallocRefInst : Instruction, UnaryInstruction {} +public protocol RefCountingInst { } -public class RefCountingInst : Instruction, UnaryInstruction {} +extension swift.StrongRetainInst : RefCountingInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } -final public class StrongRetainInst : RefCountingInst { -} + final public var next: Instruction? { SILInstruction_next(getAsSILInstruction(self)) } -final public class RetainValueInst : RefCountingInst { + final public var previous: Instruction? { SILInstruction_previous(getAsSILInstruction(self)) } } -final public class StrongReleaseInst : RefCountingInst { -} +extension swift.RetainValueInst : RefCountingInst { } -final public class ReleaseValueInst : RefCountingInst { +extension swift.StrongReleaseInst : RefCountingInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public class DestroyValueInst : Instruction, UnaryInstruction {} - -final public class DestroyAddrInst : Instruction, UnaryInstruction {} - -final public class UnimplementedRefCountingInst : RefCountingInst {} +extension swift.ReleaseValueInst : RefCountingInst { } //===----------------------------------------------------------------------===// // single-value instructions //===----------------------------------------------------------------------===// -/// Used for all SingleValueInstructions which are not implemented here, yet. -/// See registerBridgedClass() in SILBridgingUtils.cpp. -final public class UnimplementedSingleValueInst : SingleValueInstruction { -} - -final public class LoadInst : SingleValueInstruction, UnaryInstruction {} - -final public class LoadBorrowInst : SingleValueInstruction, UnaryInstruction {} - -final public class BuiltinInst : SingleValueInstruction {} - -final public class UpcastInst : SingleValueInstruction, UnaryInstruction {} - -final public -class UncheckedRefCastInst : SingleValueInstruction, UnaryInstruction {} - -final public -class RawPointerToRefInst : SingleValueInstruction, UnaryInstruction {} - -final public -class AddressToPointerInst : SingleValueInstruction, UnaryInstruction {} - -final public -class PointerToAddressInst : SingleValueInstruction, UnaryInstruction {} - -final public -class IndexAddrInst : SingleValueInstruction {} - -final public -class InitExistentialRefInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialRefInst : SingleValueInstruction, UnaryInstruction {} - -final public -class InitExistentialValueInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialValueInst : SingleValueInstruction, UnaryInstruction {} - -final public -class InitExistentialAddrInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialAddrInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialBoxInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialBoxValueInst : SingleValueInstruction, UnaryInstruction {} - -final public -class InitExistentialMetatypeInst : SingleValueInstruction, UnaryInstruction {} - -final public -class OpenExistentialMetatypeInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ValueMetatypeInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ExistentialMetatypeInst : SingleValueInstruction, UnaryInstruction {} - -public class GlobalAccessInst : SingleValueInstruction { - final public var global: GlobalVariable { - GlobalAccessInst_getGlobal(bridged).globalVar +extension swift.UpcastInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value } } -final public class GlobalAddrInst : GlobalAccessInst {} - -final public class GlobalValueInst : GlobalAccessInst {} - -final public class TupleInst : SingleValueInstruction { -} - -final public class TupleExtractInst : SingleValueInstruction, UnaryInstruction { - public var fieldIndex: Int { TupleExtractInst_fieldIndex(bridged) } -} - -final public -class TupleElementAddrInst : SingleValueInstruction, UnaryInstruction { - public var fieldIndex: Int { TupleElementAddrInst_fieldIndex(bridged) } +extension swift.UncheckedRefCastInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public class StructInst : SingleValueInstruction { +extension swift.RawPointerToRefInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public class StructExtractInst : SingleValueInstruction, UnaryInstruction { - public var fieldIndex: Int { StructExtractInst_fieldIndex(bridged) } +extension swift.AddressToPointerInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public -class StructElementAddrInst : SingleValueInstruction, UnaryInstruction { - public var fieldIndex: Int { StructElementAddrInst_fieldIndex(bridged) } +extension swift.InitExistentialRefInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public class EnumInst : SingleValueInstruction { - public var caseIndex: Int { EnumInst_caseIndex(bridged) } +extension swift.TupleExtractInst { + public var fieldIndex: Int { TupleExtractInst_fieldIndex(self) } - public var operand: Value? { operands.first?.value } + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public -class UncheckedEnumDataInst : SingleValueInstruction, UnaryInstruction { - public var caseIndex: Int { UncheckedEnumDataInst_caseIndex(bridged) } +extension swift.TupleElementAddrInst { + public var fieldIndex: Int { TupleElementAddrInst_fieldIndex(self) } } -final public class RefElementAddrInst : SingleValueInstruction, UnaryInstruction { - public var fieldIndex: Int { RefElementAddrInst_fieldIndex(bridged) } +extension swift.StructExtractInst { + public var fieldIndex: Int { StructExtractInst_fieldIndex(self) } } -final public class RefTailAddrInst : SingleValueInstruction, UnaryInstruction {} - -final public -class UnconditionalCheckedCastInst : SingleValueInstruction, UnaryInstruction { - public override var mayTrap: Bool { true } +extension swift.StructElementAddrInst { + public var fieldIndex: Int { StructElementAddrInst_fieldIndex(self) } } -final public -class UnconditionalCheckedCastValueInst : SingleValueInstruction, - UnaryInstruction { - public override var mayTrap: Bool { true } -} - -final public -class ConvertFunctionInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ThinToThickFunctionInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ObjCExistentialMetatypeToObjectInst : SingleValueInstruction, - UnaryInstruction {} - -final public -class ObjCMetatypeToObjectInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ValueToBridgeObjectInst : SingleValueInstruction, UnaryInstruction {} - -final public class BridgeObjectToRefInst : SingleValueInstruction, - UnaryInstruction {} - -final public class BeginAccessInst : SingleValueInstruction, UnaryInstruction {} - -final public class BeginBorrowInst : SingleValueInstruction, UnaryInstruction {} - -final public class CopyValueInst : SingleValueInstruction, UnaryInstruction {} - -final public class EndCOWMutationInst : SingleValueInstruction, UnaryInstruction {} - -final public -class ClassifyBridgeObjectInst : SingleValueInstruction, UnaryInstruction {} - -final public class PartialApplyInst : SingleValueInstruction, ApplySite { - public var numArguments: Int { PartialApplyInst_numArguments(bridged) } -} +extension swift.EnumInst { + final public var operands: OperandArray { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self))) + } -final public class ApplyInst : SingleValueInstruction, FullApplySite { - public var numArguments: Int { ApplyInst_numArguments(bridged) } + public var caseIndex: Int { EnumInst_caseIndex(self) } - public var singleDirectResult: Value? { self } -} - -final public class ClassMethodInst : SingleValueInstruction, UnaryInstruction {} - -final public class SuperMethodInst : SingleValueInstruction, UnaryInstruction {} - -final public class ObjCMethodInst : SingleValueInstruction, UnaryInstruction {} - -final public class ObjCSuperMethodInst : SingleValueInstruction, UnaryInstruction {} - -final public class WitnessMethodInst : SingleValueInstruction {} - - -//===----------------------------------------------------------------------===// -// single-value allocation instructions -//===----------------------------------------------------------------------===// - -public protocol Allocation : AnyObject { } - -final public class AllocStackInst : SingleValueInstruction, Allocation { + public var operand: Value? { operands.first?.value } } -final public class AllocRefInst : SingleValueInstruction, Allocation { +extension swift.UncheckedEnumDataInst { + public var caseIndex: Int { UncheckedEnumDataInst_caseIndex(self) } } -final public class AllocRefDynamicInst : SingleValueInstruction, Allocation { +extension swift.RefElementAddrInst { + public var fieldIndex: Int { RefElementAddrInst_fieldIndex(self) } } -final public class AllocBoxInst : SingleValueInstruction, Allocation { +extension swift.ConvertFunctionInst { + final public var operand: Value { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self)))[0].value + } } -final public class AllocExistentialBoxInst : SingleValueInstruction, Allocation { +extension swift.PartialApplyInst { + public var numArguments: Int { PartialApplyInst_numArguments(self) } } //===----------------------------------------------------------------------===// // multi-value instructions //===----------------------------------------------------------------------===// -final public class BeginCOWMutationInst : MultipleValueInstruction, - UnaryInstruction { - public var uniquenessResult: Value { return getResult(index: 0) } - public var bufferResult: Value { return getResult(index: 1) } -} - -final public class DestructureStructInst : MultipleValueInstruction { -} - -final public class DestructureTupleInst : MultipleValueInstruction { -} - -final public class BeginApplyInst : MultipleValueInstruction, FullApplySite { - public var numArguments: Int { BeginApplyInst_numArguments(bridged) } +extension swift.BeginApplyInst { + public var numArguments: Int { BeginApplyInst_numArguments(self) } public var singleDirectResult: Value? { nil } } @@ -476,62 +280,56 @@ final public class BeginApplyInst : MultipleValueInstruction, FullApplySite { // terminator instructions //===----------------------------------------------------------------------===// -public class TermInst : Instruction { - final public var successors: SuccessorArray { - SuccessorArray(succArray: TermInst_getSuccessors(bridged)) +extension swift.TermInst { + public var successors: SuccessorArray { + return SuccessorArray(succArray: TermInst_getSuccessors(self)) + } + + final public var operands: OperandArray { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self))) } } -final public class UnreachableInst : TermInst { -} - -final public class ReturnInst : TermInst, UnaryInstruction { -} - -final public class ThrowInst : TermInst, UnaryInstruction { -} - -final public class YieldInst : TermInst { -} - -final public class UnwindInst : TermInst { -} +extension swift.TryApplyInst { + public var successors: SuccessorArray { + return SuccessorArray(succArray: TermInst_getSuccessors(getAsTermInst(getAsSILInstruction(self))!)) + } -final public class TryApplyInst : TermInst, FullApplySite { - public var numArguments: Int { TryApplyInst_numArguments(bridged) } + public var numArguments: Int { TryApplyInst_numArguments(self) } public var normalBlock: BasicBlock { successors[0] } public var errorBlock: BasicBlock { successors[1] } - public var singleDirectResult: Value? { normalBlock.arguments[0] } + public var singleDirectResult: Value? { getAsValue(normalBlock.arguments[0]) } } -final public class BranchInst : TermInst { - public var targetBlock: BasicBlock { BranchInst_getTargetBlock(bridged).block } +extension swift.BranchInst { + public var targetBlock: BasicBlock { BranchInst_getTargetBlock(self) } public func getArgument(for operand: Operand) -> Argument { return targetBlock.arguments[operand.index] } } -final public class CondBranchInst : TermInst { -} - -final public class SwitchValueInst : TermInst { -} +extension swift.SwitchEnumInst { + public var successors: SuccessorArray { + return SuccessorArray(succArray: TermInst_getSuccessors(getAsTermInst(getAsSILInstruction(self))!)) + } -final public class SwitchEnumInst : TermInst { + final public var operands: OperandArray { + return OperandArray(opArray: SILInstruction_getOperands(getAsSILInstruction(self))) + } public var enumOp: Value { operands[0].value } public struct CaseIndexArray : RandomAccessCollection { - fileprivate let switchEnum: SwitchEnumInst + fileprivate let switchEnum: swift.SwitchEnumInst public var startIndex: Int { return 0 } - public var endIndex: Int { SwitchEnumInst_getNumCases(switchEnum.bridged) } + public var endIndex: Int { SwitchEnumInst_getNumCases(switchEnum) } public subscript(_ index: Int) -> Int { - SwitchEnumInst_getCaseIndex(switchEnum.bridged, index) + SwitchEnumInst_getCaseIndex(switchEnum, index) } } @@ -553,22 +351,3 @@ final public class SwitchEnumInst : TermInst { cases.first(where: { $0.1 == forSuccessor })?.0 } } - -final public class SwitchEnumAddrInst : TermInst { -} - -final public class DynamicMethodBranchInst : TermInst { -} - -final public class AwaitAsyncContinuationInst : TermInst, UnaryInstruction { -} - -final public class CheckedCastBranchInst : TermInst, UnaryInstruction { -} - -final public class CheckedCastAddrBranchInst : TermInst, UnaryInstruction { -} - -final public class CheckedCastValueBranchInst : TermInst, UnaryInstruction { -} - diff --git a/libswift/Sources/SIL/Operand.swift b/libswift/Sources/SIL/Operand.swift index 88bdc87eb0db7..96fb7ddce42b2 100644 --- a/libswift/Sources/SIL/Operand.swift +++ b/libswift/Sources/SIL/Operand.swift @@ -21,19 +21,15 @@ public struct Operand : CustomStringConvertible, CustomReflectable { } public var value: Value { - let v = Operand_getValue(bridged).getAs(AnyObject.self) - switch v { - case let inst as SingleValueInstruction: - return inst - case let arg as Argument: - return arg - case let mvr as MultipleValueInstructionResult: - return mvr - case let undef as Undef: - return undef - default: - fatalError("unknown Value type") + let v = Operand_getValue(bridged) + if let inst = getAsSingleValueInstruction(v) { + return getAsValue(inst)! + } else if let arg = getAsSILArgument(v) { + return getAsValue(arg)! + } else if let undef = getAsSILUndef(v) { + return getAsValue(undef)! } + fatalError("unknown Value type") } public static func ==(lhs: Operand, rhs: Operand) -> Bool { @@ -41,7 +37,7 @@ public struct Operand : CustomStringConvertible, CustomReflectable { } public var instruction: Instruction { - return Operand_getUser(bridged).instruction + return Operand_getUser(bridged) } public var index: Int { instruction.operands.getIndex(of: self) } diff --git a/libswift/Sources/SIL/Registration.swift b/libswift/Sources/SIL/Registration.swift index 4295012eecb91..8b2aa1934ee28 100644 --- a/libswift/Sources/SIL/Registration.swift +++ b/libswift/Sources/SIL/Registration.swift @@ -20,118 +20,8 @@ private func register(_ cl: T.Type) { } public func registerSILClasses() { - register(Function.self) - register(BasicBlock.self) register(GlobalVariable.self) - // The "unimplemented" registrations must be done before all other node - // registrations. In the order from super -> sub class. - register(UnimplementedInstruction.self) - register(UnimplementedSingleValueInst.self) - register(UnimplementedRefCountingInst.self) - register(MultipleValueInstructionResult.self) - - register(Undef.self) - register(PlaceholderValue.self) - register(FunctionArgument.self) register(BlockArgument.self) - - register(StoreInst.self) - register(CopyAddrInst.self) - register(EndAccessInst.self) - register(EndBorrowInst.self) - register(DeallocStackInst.self) - register(CondFailInst.self) - register(FixLifetimeInst.self) - register(DebugValueInst.self) - register(UnconditionalCheckedCastAddrInst.self) - register(SetDeallocatingInst.self) - register(DeallocRefInst.self) - register(StrongRetainInst.self) - register(RetainValueInst.self) - register(StrongReleaseInst.self) - register(ReleaseValueInst.self) - register(DestroyValueInst.self) - register(DestroyAddrInst.self) - register(LoadInst.self) - register(LoadBorrowInst.self) - register(BuiltinInst.self) - register(UpcastInst.self) - register(UncheckedRefCastInst.self) - register(RawPointerToRefInst.self) - register(AddressToPointerInst.self) - register(PointerToAddressInst.self) - register(IndexAddrInst.self) - register(InitExistentialRefInst.self) - register(OpenExistentialRefInst.self) - register(InitExistentialValueInst.self) - register(OpenExistentialValueInst.self) - register(InitExistentialAddrInst.self) - register(OpenExistentialAddrInst.self) - register(OpenExistentialBoxInst.self) - register(OpenExistentialBoxValueInst.self) - register(InitExistentialMetatypeInst.self) - register(OpenExistentialMetatypeInst.self) - register(ValueMetatypeInst.self) - register(ExistentialMetatypeInst.self) - register(GlobalAddrInst.self) - register(GlobalValueInst.self) - register(TupleInst.self) - register(TupleExtractInst.self) - register(TupleElementAddrInst.self) - register(StructInst.self) - register(StructExtractInst.self) - register(StructElementAddrInst.self) - register(EnumInst.self) - register(UncheckedEnumDataInst.self) - register(RefElementAddrInst.self) - register(RefTailAddrInst.self) - register(UnconditionalCheckedCastInst.self) - register(UnconditionalCheckedCastValueInst.self) - register(ConvertFunctionInst.self) - register(ThinToThickFunctionInst.self) - register(ObjCExistentialMetatypeToObjectInst.self) - register(ObjCMetatypeToObjectInst.self) - register(ValueToBridgeObjectInst.self) - register(BridgeObjectToRefInst.self) - register(BeginAccessInst.self) - register(BeginBorrowInst.self) - register(CopyValueInst.self) - register(EndCOWMutationInst.self) - register(ClassifyBridgeObjectInst.self) - register(PartialApplyInst.self) - register(ApplyInst.self) - register(ClassMethodInst.self) - register(SuperMethodInst.self) - register(ObjCMethodInst.self) - register(ObjCSuperMethodInst.self) - register(WitnessMethodInst.self) - register(AllocStackInst.self) - register(AllocRefInst.self) - register(AllocRefDynamicInst.self) - register(AllocBoxInst.self) - register(AllocExistentialBoxInst.self) - - register(BeginCOWMutationInst.self) - register(DestructureStructInst.self) - register(DestructureTupleInst.self) - register(BeginApplyInst.self) - - register(UnreachableInst.self) - register(ReturnInst.self) - register(ThrowInst.self) - register(YieldInst.self) - register(UnwindInst.self) - register(TryApplyInst.self) - register(BranchInst.self) - register(CondBranchInst.self) - register(SwitchValueInst.self) - register(SwitchEnumInst.self) - register(SwitchEnumAddrInst.self) - register(DynamicMethodBranchInst.self) - register(AwaitAsyncContinuationInst.self) - register(CheckedCastBranchInst.self) - register(CheckedCastAddrBranchInst.self) - register(CheckedCastValueBranchInst.self) } diff --git a/libswift/Sources/SIL/Type.swift b/libswift/Sources/SIL/Type.swift index 3cddf6fe2f9e8..14016a3188ee2 100644 --- a/libswift/Sources/SIL/Type.swift +++ b/libswift/Sources/SIL/Type.swift @@ -12,13 +12,13 @@ import SILBridging -public struct Type { - var bridged: BridgedType - - public var isAddress: Bool { SILType_isAddress(bridged) != 0 } +public typealias Type = swift.SILType + +extension swift.SILType { + public var isAddress: Bool { SILType_isAddress(self) != 0 } public var isObject: Bool { !isAddress } public func isTrivial(in function: Function) -> Bool { - return SILType_isTrivial(bridged, function.bridged) != 0 + return SILType_isTrivial(self, function) != 0 } } diff --git a/libswift/Sources/SIL/Utils.swift b/libswift/Sources/SIL/Utils.swift index 6444c182e2c0c..a35e40a58e127 100644 --- a/libswift/Sources/SIL/Utils.swift +++ b/libswift/Sources/SIL/Utils.swift @@ -16,7 +16,7 @@ import SILBridging // Lists //===----------------------------------------------------------------------===// -public protocol ListNode : AnyObject { +public protocol ListNode { associatedtype Element var next: Element? { get } var previous: Element? { get } @@ -27,7 +27,10 @@ public struct List : where NodeType.Element == NodeType { private var currentNode: NodeType? - public init(startAt: NodeType?) { currentNode = startAt } + public init(startAt: NodeType?) { + print("Init...") + currentNode = startAt + } public mutating func next() -> NodeType? { if let node = currentNode { diff --git a/libswift/Sources/SIL/Value.swift b/libswift/Sources/SIL/Value.swift index 2ec13733c442c..a59fa00ce71e1 100644 --- a/libswift/Sources/SIL/Value.swift +++ b/libswift/Sources/SIL/Value.swift @@ -12,50 +12,17 @@ import SILBridging -public protocol Value : AnyObject, CustomStringConvertible { - var uses: UseList { get } - var type: Type { get } - var definingInstruction: Instruction? { get } -} +public typealias Value = swift.ValueBase extension Value { public var description: String { - var s = SILNode_debugDescription(bridgedNode) + var s = SILNode_debugDescription(self) return String(cString: s.c_str()) } - public var uses: UseList { - return UseList(SILValue_firstUse(bridged)) - } - - public var type: Type { - return Type(bridged: SILValue_getType(bridged)) - } - - public var hashable: HashableValue { ObjectIdentifier(self) } + public var uses: UseList { UseList(SILValue_firstUse(self)) } - public var bridged: BridgedValue { - BridgedValue(obj: SwiftObject(self as AnyObject)) - } - var bridgedNode: BridgedNode { - BridgedNode(obj: SwiftObject(self as AnyObject)) - } + public var type: Type { SILValue_getType(self) } } -public typealias HashableValue = ObjectIdentifier - -public func ==(_ lhs: Value, _ rhs: Value) -> Bool { - return lhs === rhs -} - -extension BridgedValue { - func getAs(_ valueType: T.Type) -> T { obj.getAs(T.self) } -} - -final class Undef : Value { - public var definingInstruction: Instruction? { nil } -} - -final class PlaceholderValue : Value { - public var definingInstruction: Instruction? { nil } -} +public func==(_ a: Value, _ b: Value) -> Bool { isPtrEq(a, b) } diff --git a/test/Interop/Cxx/foreign-reference/Inputs/module.modulemap b/test/Interop/Cxx/foreign-reference/Inputs/module.modulemap new file mode 100644 index 0000000000000..fa71e36cb6c92 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/module.modulemap @@ -0,0 +1,24 @@ +module POD { + header "pod.h" + requires cplusplus +} + +module MoveOnly { + header "move-only.h" + requires cplusplus +} + +module Singleton { + header "singleton.h" + requires cplusplus +} + +module Nullable { + header "nullable.h" + requires cplusplus +} + +module WitnessTable { + header "witness-table.h" + requires cplusplus +} diff --git a/test/Interop/Cxx/foreign-reference/Inputs/move-only.h b/test/Interop/Cxx/foreign-reference/Inputs/move-only.h new file mode 100644 index 0000000000000..ebaba3ad77932 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/move-only.h @@ -0,0 +1,71 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_MOVE_ONLY_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_MOVE_ONLY_H + +#include +#include +#include + +#include "visibility.h" + +SWIFT_BEGIN_NULLABILITY_ANNOTATIONS + +struct __attribute__((swift_attr("import_as_ref"))) MoveOnly { + MoveOnly() = default; + MoveOnly(const MoveOnly &) = delete; + MoveOnly(MoveOnly &&) = default; + + int test() const { return 42; } + int testMutable() { return 42; } + + static MoveOnly *create() { + return new (malloc(sizeof(MoveOnly))) MoveOnly(); + } +}; + +MoveOnly moveIntoResult(MoveOnly &x) { return std::move(x); } + +struct __attribute__((swift_attr("import_as_ref"))) HasMoveOnlyChild { + MoveOnly child; + + static HasMoveOnlyChild *create() { + return new (malloc(sizeof(HasMoveOnlyChild))) HasMoveOnlyChild(); + } +}; + +HasMoveOnlyChild moveIntoResult(HasMoveOnlyChild &x) { return std::move(x); } + +struct __attribute__((swift_attr("import_as_ref"))) PrivateCopyCtor { + PrivateCopyCtor() = default; + PrivateCopyCtor(PrivateCopyCtor &&) = default; + + int test() const { return 42; } + int testMutable() { return 42; } + + static PrivateCopyCtor *create() { + return new (malloc(sizeof(PrivateCopyCtor))) PrivateCopyCtor(); + } + +private: + PrivateCopyCtor(const PrivateCopyCtor &) {} +}; + +PrivateCopyCtor moveIntoResult(PrivateCopyCtor &x) { return std::move(x); } + +struct __attribute__((swift_attr("import_as_ref"))) BadCopyCtor { + BadCopyCtor() = default; + BadCopyCtor(BadCopyCtor &&) = default; + BadCopyCtor(const BadCopyCtor &) { __builtin_trap(); } + + int test() const { return 42; } + int testMutable() { return 42; } + + static BadCopyCtor *create() { + return new (malloc(sizeof(BadCopyCtor))) BadCopyCtor(); + } +}; + +BadCopyCtor moveIntoResult(BadCopyCtor &x) { return std::move(x); } + +SWIFT_END_NULLABILITY_ANNOTATIONS + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_MOVE_ONLY_H diff --git a/test/Interop/Cxx/foreign-reference/Inputs/nullable.h b/test/Interop/Cxx/foreign-reference/Inputs/nullable.h new file mode 100644 index 0000000000000..c71e8547b7ba6 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/nullable.h @@ -0,0 +1,29 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_NULLABLE_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_NULLABLE_H + +#include +#include + +struct __attribute__((swift_attr("import_as_ref"))) Empty { + int test() const { return 42; } + + static Empty *create() { return new (malloc(sizeof(Empty))) Empty(); } +}; + +void mutateIt(Empty &) {} + +struct __attribute__((swift_attr("import_as_ref"))) IntPair { + int a = 1; + int b = 2; + + int test() const { return b - a; } + + static IntPair *create() { return new (malloc(sizeof(IntPair))) IntPair(); } +}; + +void mutateIt(IntPair *x) { + x->a = 2; + x->b = 4; +} + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_NULLABLE_H diff --git a/test/Interop/Cxx/foreign-reference/Inputs/pod.h b/test/Interop/Cxx/foreign-reference/Inputs/pod.h new file mode 100644 index 0000000000000..94e32077395d8 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/pod.h @@ -0,0 +1,121 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_POD_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_POD_H + +#include +#include + +#include "visibility.h" + +SWIFT_BEGIN_NULLABILITY_ANNOTATIONS + +struct __attribute__((swift_attr("import_as_ref"))) Empty { + int test() const { return 42; } + int testMutable() { return 42; } + + static Empty *create() { return new (malloc(sizeof(Empty))) Empty(); } +}; + +void mutateIt(Empty &) {} +Empty passThroughByValue(Empty x) { return x; } + +struct __attribute__((swift_attr("@actor"))) +__attribute__((swift_attr("import_as_ref"))) MultipleAttrs { + int test() const { return 42; } + int testMutable() { return 42; } + + static MultipleAttrs *create() { + return new (malloc(sizeof(MultipleAttrs))) MultipleAttrs(); + } +}; + +struct __attribute__((swift_attr("import_as_ref"))) IntPair { + int a = 1; + int b = 2; + + int test() const { return b - a; } + int testMutable() { return b - a; } + + static IntPair *create() { return new (malloc(sizeof(IntPair))) IntPair(); } +}; + +void mutateIt(IntPair &x) { + x.a = 2; + x.b = 4; +} +IntPair passThroughByValue(IntPair x) { return x; } + +struct __attribute__((swift_attr("import_as_ref"))) RefHoldingPair { + // REVIEW-NOTE: I added support for this but then removed it, as this sort of + // indicates incorrect usage of a "reference type" and has weird semantics. + IntPair pair; + int otherValue = 3; + + int test() const { return otherValue - pair.test(); } + int testMutable() { return otherValue - pair.test(); } + + static RefHoldingPair *create() { + return new (malloc(sizeof(RefHoldingPair))) RefHoldingPair(); + } +}; + +struct __attribute__((swift_attr("import_as_ref"))) RefHoldingPairRef { + IntPair &pair; + int otherValue; + RefHoldingPairRef(IntPair &pair) : pair(pair), otherValue(42) {} + + int test() const { return otherValue - pair.test(); } + int testMutable() { return otherValue - pair.test(); } + + static RefHoldingPairRef *create() { + IntPair *pair = new (malloc(sizeof(IntPair))) IntPair(); + return new (malloc(sizeof(RefHoldingPairRef))) RefHoldingPairRef(*pair); + } +}; + +struct __attribute__((swift_attr("import_as_ref"))) RefHoldingPairPtr { + IntPair *pair; + int otherValue = 42; + + int test() const { return otherValue - pair->test(); } + int testMutable() { return otherValue - pair->test(); } + + static RefHoldingPairPtr *create() { + RefHoldingPairPtr *out = + new (malloc(sizeof(RefHoldingPairPtr))) RefHoldingPairPtr(); + out->pair = new (malloc(sizeof(IntPair))) IntPair(); + return out; + } +}; + +struct ValueHoldingPair { + IntPair pair; + int otherValue = 3; + + int test() const { return otherValue - pair.test(); } + int testMutable() { return otherValue - pair.test(); } + + static ValueHoldingPair *create() { + return new (malloc(sizeof(ValueHoldingPair))) ValueHoldingPair(); + } +}; + +struct __attribute__((swift_attr("import_as_ref"))) BigType { + int a = 1; + int b = 2; + char buffer[32]; + + int test() const { return b - a; } + int testMutable() { return b - a; } + + static BigType *create() { return new (malloc(sizeof(BigType))) BigType(); } +}; + +void mutateIt(BigType &x) { + x.a = 2; + x.b = 4; +} +BigType passThroughByValue(BigType x) { return x; } + +SWIFT_END_NULLABILITY_ANNOTATIONS + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_POD_H diff --git a/test/Interop/Cxx/foreign-reference/Inputs/singleton.h b/test/Interop/Cxx/foreign-reference/Inputs/singleton.h new file mode 100644 index 0000000000000..5e12ad7ce4405 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/singleton.h @@ -0,0 +1,89 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_SINGLETON_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_SINGLETON_H + +#include +#include + +#include "visibility.h" + +SWIFT_BEGIN_NULLABILITY_ANNOTATIONS + +struct __attribute__((swift_attr("import_as_ref"))) DeletedDtor { + int value = 42; + + DeletedDtor() = default; + DeletedDtor(const DeletedDtor &) = default; + DeletedDtor(DeletedDtor &&) = default; + ~DeletedDtor() = delete; + + int test() const { return value; } + int testMutable() { return value; } + + static DeletedDtor *create() { + return new (malloc(sizeof(DeletedDtor))) DeletedDtor(); + } +}; + +void mutateIt(DeletedDtor &x) { x.value = 32; } + +struct __attribute__((swift_attr("import_as_ref"))) PrivateDtor { + int value = 42; + + PrivateDtor() = default; + PrivateDtor(const PrivateDtor &) = default; + PrivateDtor(PrivateDtor &&) = default; + + int test() const { return value; } + int testMutable() { return value; } + + static PrivateDtor *create() { + return new (malloc(sizeof(PrivateDtor))) PrivateDtor(); + } + +private: + ~PrivateDtor() {} +}; + +void mutateIt(PrivateDtor &x) { x.value = 32; } + +struct __attribute__((swift_attr("import_as_ref"))) DeletedSpecialMembers { + int value = 42; + + DeletedSpecialMembers() = default; + DeletedSpecialMembers(const DeletedSpecialMembers &) = delete; + DeletedSpecialMembers(DeletedSpecialMembers &&) = delete; + ~DeletedSpecialMembers() = delete; + + int test() const { return value; } + int testMutable() { return value; } + + static DeletedSpecialMembers *create() { + return new (malloc(sizeof(DeletedSpecialMembers))) DeletedSpecialMembers(); + } +}; + +void mutateIt(DeletedSpecialMembers &x) { x.value = 32; } + +struct __attribute__((swift_attr("import_as_ref"))) PrivateSpecialMembers { + int value = 42; + + PrivateSpecialMembers() = default; + + int test() const { return value; } + int testMutable() { return value; } + + static PrivateSpecialMembers *create() { + return new (malloc(sizeof(PrivateSpecialMembers))) PrivateSpecialMembers(); + } + +private: + PrivateSpecialMembers(const PrivateSpecialMembers &) = default; + PrivateSpecialMembers(PrivateSpecialMembers &&) = default; + ~PrivateSpecialMembers() = default; +}; + +void mutateIt(PrivateSpecialMembers &x) { x.value = 32; } + +SWIFT_END_NULLABILITY_ANNOTATIONS + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_SINGLETON_H diff --git a/test/Interop/Cxx/foreign-reference/Inputs/visibility.h b/test/Interop/Cxx/foreign-reference/Inputs/visibility.h new file mode 100644 index 0000000000000..5eeb5b032bcee --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/visibility.h @@ -0,0 +1,25 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_VISIBILITY_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_VISIBILITY_H + +#if __has_feature(nullability) +// Provide macros to temporarily suppress warning about the use of +// _Nullable and _Nonnull. +# define SWIFT_BEGIN_NULLABILITY_ANNOTATIONS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wnullability-extension\"") \ + _Pragma("clang assume_nonnull begin") +# define SWIFT_END_NULLABILITY_ANNOTATIONS \ + _Pragma("clang diagnostic pop") \ + _Pragma("clang assume_nonnull end") + +#else +// #define _Nullable and _Nonnull to nothing if we're not being built +// with a compiler that supports them. +# define _Nullable +# define _Nonnull +# define _Null_unspecified +# define SWIFT_BEGIN_NULLABILITY_ANNOTATIONS +# define SWIFT_END_NULLABILITY_ANNOTATIONS +#endif + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_VISIBILITY_H diff --git a/test/Interop/Cxx/foreign-reference/Inputs/witness-table.h b/test/Interop/Cxx/foreign-reference/Inputs/witness-table.h new file mode 100644 index 0000000000000..1a33378a0baa0 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/Inputs/witness-table.h @@ -0,0 +1,53 @@ +#ifndef TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_WITNESS_TABLE_H +#define TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_WITNESS_TABLE_H + +#include +#include +#include + +struct __attribute__((swift_attr("import_as_ref"))) CxxLinkedList { + int value = 3; + + CxxLinkedList * _Nullable next() { + if (value == 3) + return nullptr; + + return this + 1; + } +}; + +CxxLinkedList * _Nonnull makeLinkedList() { + CxxLinkedList *buff = (CxxLinkedList *)malloc(sizeof(CxxLinkedList) * 4); + buff[0].value = 0; + buff[1].value = 1; + buff[2].value = 2; + buff[3].value = 3; + return buff; +} + +struct __attribute__((swift_attr("import_as_ref"))) CxxSequence { + CxxLinkedList * _Nullable list = nullptr; + + CxxLinkedList * _Nullable next() { + if (list->value == 3) + return nullptr; + + auto * _Nullable tmp = list; + list = tmp + 1; + return tmp; + } +}; + +CxxSequence * _Nonnull makeSequence() { + CxxLinkedList *buff = (CxxLinkedList *)malloc(sizeof(CxxLinkedList) * 4); + buff[0].value = 0; + buff[1].value = 1; + buff[2].value = 2; + buff[3].value = 3; + + CxxSequence *seq = (CxxSequence *)malloc(sizeof(CxxSequence)); + seq->list = buff; + return seq; +} + +#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_WITNESS_TABLE_H diff --git a/test/Interop/Cxx/foreign-reference/move-only-irgen.swift b/test/Interop/Cxx/foreign-reference/move-only-irgen.swift new file mode 100644 index 0000000000000..b008ca1f81362 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/move-only-irgen.swift @@ -0,0 +1,29 @@ +// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop -validate-tbd-against-ir=none -disable-llvm-verify | %FileCheck %s + +import MoveOnly + +// TODO: this should not be opaque. +// CHECK: %TSo8MoveOnlyV = type opaque +// CHECK: %struct.MoveOnly = type { i8 } + + +// CHECK-LABEL: define swiftcc void @"$s4main4testyyF" + +// CHECK: [[X:%.*]] = alloca %TSo8MoveOnlyV* +// CHECK: [[TMP:%.*]] = alloca %TSo8MoveOnlyV* + +// CHECK: [[CREATED:%.*]] = call %struct.MoveOnly* @_ZN8MoveOnly6createEv() +// CHECK: [[SWIFT_CREATED:%.*]] = bitcast %struct.MoveOnly* [[CREATED]] to %TSo8MoveOnlyV* +// CHECK: store %TSo8MoveOnlyV* [[SWIFT_CREATED]], %TSo8MoveOnlyV** [[X]] +// CHECK: store %TSo8MoveOnlyV* [[SWIFT_CREATED]], %TSo8MoveOnlyV** [[TMP]] + +// CHECK: [[TMP_LOAD:%.*]] = load %TSo8MoveOnlyV*, %TSo8MoveOnlyV** [[TMP]] +// CHECK: [[CLANG_CREATED:%.*]] = bitcast %TSo8MoveOnlyV* [[TMP_LOAD]] to %struct.MoveOnly* +// CHECK: call i32 @_ZNK8MoveOnly4testEv(%struct.MoveOnly* [[CLANG_CREATED]]) + +// CHECK: ret void + +public func test() { + var x = MoveOnly.create() + _ = x.test() +} diff --git a/test/Interop/Cxx/foreign-reference/move-only-module-interface.swift b/test/Interop/Cxx/foreign-reference/move-only-module-interface.swift new file mode 100644 index 0000000000000..57aaa8f739c9b --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/move-only-module-interface.swift @@ -0,0 +1,29 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=MoveOnly -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s + +// CHECK-NOT: init +// CHECK: class MoveOnly { +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> MoveOnly +// CHECK: } +// CHECK-NOT: func moveIntoResult(_ x: MoveOnly) -> MoveOnly + +// CHECK: class HasMoveOnlyChild { +// CHECK-NOT: var child: MoveOnly +// CHECK: class func create() -> HasMoveOnlyChild +// CHECK: } +// CHECK-NOT: func moveIntoResult(_ x: HasMoveOnlyChild) -> HasMoveOnlyChild + +// CHECK: class PrivateCopyCtor { +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> PrivateCopyCtor +// CHECK: } +// CHECK-NOT: func moveIntoResult(_ x: PrivateCopyCtor) -> PrivateCopyCtor + +// CHECK: class BadCopyCtor { +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> BadCopyCtor +// CHECK: } +// CHECK-NOT: func moveIntoResult(_ x: BadCopyCtor) -> BadCopyCtor diff --git a/test/Interop/Cxx/foreign-reference/move-only-silgen.swift b/test/Interop/Cxx/foreign-reference/move-only-silgen.swift new file mode 100644 index 0000000000000..ec26313607b2d --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/move-only-silgen.swift @@ -0,0 +1,33 @@ +// RUN: %target-swift-emit-silgen %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s + +import MoveOnly + +// CHECK-NOT: borrow +// CHECK-NOT: retain +// CHECK-NOT: release +// CHECK-LABEL: sil [ossa] @$s4main4testyyF : $@convention(thin) () -> () + +// CHECK: [[BOX:%.*]] = project_box {{.*}} : ${ var MoveOnly }, 0 + +// CHECK: [[CREATE_FN:%.*]] = function_ref @_ZN8MoveOnly6createEv : $@convention(c) () -> MoveOnly +// CHECK: [[CREATED_PTR:%.*]] = apply [[CREATE_FN]]() : $@convention(c) () -> MoveOnly +// CHECK: store [[CREATED_PTR]] to [trivial] [[BOX]] : $*MoveOnly +// CHECK: [[ACCESS_1:%.*]] = begin_access [read] [unknown] [[BOX]] : $*MoveOnly +// CHECK: [[X_1:%.*]] = load [trivial] [[ACCESS_1]] : $*MoveOnly + +// CHECK: [[TMP:%.*]] = alloc_stack $MoveOnly +// CHECK: store [[X_1]] to [trivial] [[TMP]] + +// CHECK: [[TEST_FN:%.*]] = function_ref @_ZNK8MoveOnly4testEv : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 + +// CHECK: return +// CHECK-LABEL: end sil function '$s4main4testyyF' +public func test() { + var x = MoveOnly.create() + _ = x.test() +} + +// CHECK-LABEL: sil [clang MoveOnly.create] @_ZN8MoveOnly6createEv : $@convention(c) () -> MoveOnly + +// CHECK-LABEL: sil [clang MoveOnly.test] @_ZNK8MoveOnly4testEv : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 diff --git a/test/Interop/Cxx/foreign-reference/move-only.swift b/test/Interop/Cxx/foreign-reference/move-only.swift new file mode 100644 index 0000000000000..ce5f35e1504a2 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/move-only.swift @@ -0,0 +1,43 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify) +// +// REQUIRES: executable_test + +import StdlibUnittest +import MoveOnly + +@inline(never) +func blackHole(_ t: T) { } + +var MoveOnlyTestSuite = TestSuite("Move only types that are marked as foreign references") + +MoveOnlyTestSuite.test("MoveOnly") { + var x = MoveOnly.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + x = MoveOnly.create() + expectEqual(x.test(), 42) +} + +MoveOnlyTestSuite.test("PrivateCopyCtor") { + var x = PrivateCopyCtor.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + x = PrivateCopyCtor.create() + expectEqual(x.test(), 42) +} + +MoveOnlyTestSuite.test("BadCopyCtor") { + var x = BadCopyCtor.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + x = BadCopyCtor.create() + expectEqual(x.test(), 42) + + let t = (x, x) // Copy this around just to make sure we don't call the copy ctor. + blackHole(t) +} + +runAllTests() diff --git a/test/Interop/Cxx/foreign-reference/not-any-object.swift b/test/Interop/Cxx/foreign-reference/not-any-object.swift new file mode 100644 index 0000000000000..4579b6e7ccb49 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/not-any-object.swift @@ -0,0 +1,26 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: %target-swift-frontend -typecheck -verify -verify-ignore-unknown -I %t/Inputs %t/test.swift -enable-cxx-interop + +//--- Inputs/module.modulemap +module Test { + header "test.h" + requires cplusplus +} + +//--- Inputs/test.h +#include +#include + +struct __attribute__((swift_attr("import_as_ref"))) Empty { + static Empty *create() { return new (malloc(sizeof(Empty))) Empty(); } +}; + +//--- test.swift + +import Test; + +public func test(_ _: AnyObject) {} + +// TODO: make this a better error. +test(Empty.create()) // expected-error {{type of expression is ambiguous without more context}} diff --git a/test/Interop/Cxx/foreign-reference/nullable-module-interface.swift b/test/Interop/Cxx/foreign-reference/nullable-module-interface.swift new file mode 100644 index 0000000000000..34738ac0d2908 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/nullable-module-interface.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=Nullable -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s + +// CHECK: class Empty { +// CHECK: func test() -> Int32 +// CHECK: class func create() -> Empty! +// CHECK: init() +// CHECK: } +// CHECK: func mutateIt(_: Empty) + +// CHECK: class IntPair { +// CHECK: var a: Int32 +// CHECK: var b: Int32 +// CHECK: func test() -> Int32 +// CHECK: class func create() -> IntPair! +// CHECK: init() +// CHECK: } +// CHECK: func mutateIt(_ x: IntPair!) diff --git a/test/Interop/Cxx/foreign-reference/nullable.swift b/test/Interop/Cxx/foreign-reference/nullable.swift new file mode 100644 index 0000000000000..a92380f9dcd5b --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/nullable.swift @@ -0,0 +1,34 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify -g) +// +// REQUIRES: executable_test + +import StdlibUnittest +import Nullable + +var NullableTestSuite = TestSuite("Foreign references that are nullable") + +NullableTestSuite.test("Empty") { + var x = Empty.create() + expectEqual(x!.test(), 42) + + mutateIt(x!) + + x = Empty.create() ?? Empty.create()! + expectEqual(x!.test(), 42) +} + +NullableTestSuite.test("IntPair") { + var x = IntPair.create() + expectEqual(x!.test(), 1) + + mutateIt(x) + expectEqual(x!.test(), 2) + + x!.b = 42 + expectEqual(x!.test(), 40) + + x = IntPair.create() ?? IntPair.create()! + expectEqual(x!.test(), 1) +} + +runAllTests() diff --git a/test/Interop/Cxx/foreign-reference/pod-irgen.swift b/test/Interop/Cxx/foreign-reference/pod-irgen.swift new file mode 100644 index 0000000000000..2c5f75b1658ea --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/pod-irgen.swift @@ -0,0 +1,28 @@ +// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop -validate-tbd-against-ir=none -disable-llvm-verify | %FileCheck %s + +import POD + +// TODO: this should not be opaque. +// CHECK: %TSo7IntPairV = type opaque +// CHECK: %struct.IntPair = type { i32, i32 } + +// CHECK-LABEL: define swiftcc void @"$s4main4testyyF" + +// CHECK: [[X:%.*]] = alloca %TSo7IntPairV* +// CHECK: [[TMP:%.*]] = alloca %TSo7IntPairV* + +// CHECK: [[CREATED:%.*]] = call %struct.IntPair* @_ZN7IntPair6createEv() +// CHECK: [[SWIFT_CREATED:%.*]] = bitcast %struct.IntPair* [[CREATED]] to %TSo7IntPairV* +// CHECK: store %TSo7IntPairV* [[SWIFT_CREATED]], %TSo7IntPairV** [[X]] +// CHECK: store %TSo7IntPairV* [[SWIFT_CREATED]], %TSo7IntPairV** [[TMP]] + +// CHECK: [[TMP_LOAD:%.*]] = load %TSo7IntPairV*, %TSo7IntPairV** [[TMP]] +// CHECK: [[CLANG_CREATED:%.*]] = bitcast %TSo7IntPairV* [[TMP_LOAD]] to %struct.IntPair* +// CHECK: call i32 @_ZNK7IntPair4testEv(%struct.IntPair* [[CLANG_CREATED]]) + +// CHECK: ret void + +public func test() { + var x = IntPair.create() + _ = x.test() +} diff --git a/test/Interop/Cxx/foreign-reference/pod-module-interface.swift b/test/Interop/Cxx/foreign-reference/pod-module-interface.swift new file mode 100644 index 0000000000000..260eab2723a2e --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/pod-module-interface.swift @@ -0,0 +1,70 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=POD -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s + +// CHECK-NOT: init +// CHECK: class Empty { +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> Empty +// CHECK: } +// CHECK: func mutateIt(_: Empty) +// CHECK-NOT: func passThroughByValue(_ x: Empty) -> Empty + +// CHECK: class MultipleAttrs { +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> MultipleAttrs +// CHECK: } + +// CHECK: class IntPair { +// CHECK: var a: Int32 +// CHECK: var b: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> IntPair +// CHECK: } +// CHECK: func mutateIt(_ x: IntPair) +// CHECK-NOT: func passThroughByValue(_ x: IntPair) -> IntPair + +// CHECK: class RefHoldingPair { +// CHECK-NOT: pair +// CHECK: var otherValue: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> RefHoldingPair +// CHECK: } + +// CHECK: class RefHoldingPairRef { +// CHECK: var pair: IntPair +// CHECK: var otherValue: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> RefHoldingPairRef +// CHECK: } + +// CHECK: class RefHoldingPairPtr { +// CHECK: var pair: IntPair +// CHECK: var otherValue: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> RefHoldingPairPtr +// CHECK: } + +// CHECK: struct ValueHoldingPair { +// CHECK-NOT: pair +// CHECK: init() +// CHECK: var otherValue: Int32 +// CHECK: func test() -> Int32 +// CHECK: mutating func testMutable() -> Int32 +// CHECK: static func create() -> UnsafeMutablePointer +// CHECK: } + +// CHECK: class BigType { +// CHECK: var a: Int32 +// CHECK: var b: Int32 +// CHECK: var buffer: +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> BigType +// CHECK: } +// CHECK: func mutateIt(_ x: BigType) +// CHECK-NOT: func passThroughByValue(_ x: BigType) -> BigType diff --git a/test/Interop/Cxx/foreign-reference/pod-silgen.swift b/test/Interop/Cxx/foreign-reference/pod-silgen.swift new file mode 100644 index 0000000000000..711daa51d2cf8 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/pod-silgen.swift @@ -0,0 +1,32 @@ +// RUN: %target-swift-emit-silgen %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s + +import POD + +// CHECK-NOT: borrow +// CHECK-NOT: retain +// CHECK-NOT: release +// CHECK-LABEL: sil [ossa] @$s4main4testyyF : $@convention(thin) () -> () + +// CHECK: [[BOX:%.*]] = project_box {{.*}} : ${ var IntPair }, 0 + +// CHECK: [[CREATE_FN:%.*]] = function_ref @_ZN7IntPair6createEv : $@convention(c) () -> IntPair +// CHECK: [[CREATED_PTR:%.*]] = apply [[CREATE_FN]]() : $@convention(c) () -> IntPair +// CHECK: store [[CREATED_PTR]] to [trivial] [[BOX]] : $*IntPair +// CHECK: [[ACCESS_1:%.*]] = begin_access [read] [unknown] [[BOX]] : $*IntPair +// CHECK: [[X_1:%.*]] = load [trivial] [[ACCESS_1]] : $*IntPair + +// CHECK: [[TMP:%.*]] = alloc_stack $IntPair +// CHECK: store [[X_1]] to [trivial] [[TMP]] +// CHECK: [[TEST_FN:%.*]] = function_ref @_ZNK7IntPair4testEv : $@convention(c) (@in_guaranteed IntPair) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed IntPair) -> Int32 + +// CHECK: return +// CHECK-LABEL: end sil function '$s4main4testyyF' +public func test() { + var x = IntPair.create() + _ = x.test() +} + +// CHECK-LABEL: sil [clang IntPair.create] @_ZN7IntPair6createEv : $@convention(c) () -> IntPair + +// CHECK-LABEL: sil [clang IntPair.test] @_ZNK7IntPair4testEv : $@convention(c) (@in_guaranteed IntPair) -> Int32 diff --git a/test/Interop/Cxx/foreign-reference/pod.swift b/test/Interop/Cxx/foreign-reference/pod.swift new file mode 100644 index 0000000000000..9a7a8c88cb0cc --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/pod.swift @@ -0,0 +1,150 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify -g) +// +// REQUIRES: executable_test + +import StdlibUnittest +import POD + +struct StructHoldingPair { + var pair: IntPair +}; + +class ClassHoldingPair { + var pair: IntPair + + init(pair: IntPair) { self.pair = pair } +}; + +var globalPair: IntPair? = nil + +var PODTestSuite = TestSuite("Plain old data types that are marked as foreign references") + +PODTestSuite.test("Empty") { + var x = Empty.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + mutateIt(x) + + x = Empty.create() + expectEqual(x.test(), 42) +} + +PODTestSuite.test("var IntPair") { + var x = IntPair.create() + expectEqual(x.test(), 1) + expectEqual(x.testMutable(), 1) + + mutateIt(x) + expectEqual(x.test(), 2) + expectEqual(x.testMutable(), 2) + + x.b = 42 + expectEqual(x.test(), 40) + expectEqual(x.testMutable(), 40) + + x = IntPair.create() + expectEqual(x.test(), 1) +} + +PODTestSuite.test("let IntPair") { + let x = IntPair.create() + expectEqual(x.test(), 1) + expectEqual(x.testMutable(), 1) + + mutateIt(x) + expectEqual(x.test(), 2) + expectEqual(x.testMutable(), 2) + + x.b = 42 + expectEqual(x.test(), 40) + expectEqual(x.testMutable(), 40) +} + +PODTestSuite.test("global") { + globalPair = IntPair.create() + expectEqual(globalPair!.test(), 1) + expectEqual(globalPair!.testMutable(), 1) + + mutateIt(globalPair!) + expectEqual(globalPair!.test(), 2) + expectEqual(globalPair!.testMutable(), 2) + + globalPair!.b = 42 + expectEqual(globalPair!.test(), 40) + expectEqual(globalPair!.testMutable(), 40) + + globalPair = IntPair.create() + expectEqual(globalPair!.test(), 1) +} + +PODTestSuite.test("RefHoldingPairRef") { + var x = RefHoldingPairRef.create() + expectEqual(x.test(), 41) + expectEqual(x.testMutable(), 41) + + x.pair.b = 42 + expectEqual(x.test(), 1) + expectEqual(x.testMutable(), 1) + + x = RefHoldingPairRef.create() + expectEqual(x.test(), 41) +} + +PODTestSuite.test("RefHoldingPairPtr") { + var x = RefHoldingPairPtr.create() + expectEqual(x.test(), 41) + expectEqual(x.testMutable(), 41) + + x.pair.b = 42 + expectEqual(x.test(), 1) + expectEqual(x.testMutable(), 1) + + x = RefHoldingPairPtr.create() + expectEqual(x.test(), 41) +} + +PODTestSuite.test("StructHoldingPair") { + var x = StructHoldingPair(pair: IntPair.create()) + expectEqual(x.pair.test(), 1) + expectEqual(x.pair.testMutable(), 1) + + mutateIt(x.pair) + expectEqual(x.pair.test(), 2) + expectEqual(x.pair.testMutable(), 2) + + x.pair = IntPair.create() + expectEqual(x.pair.test(), 1) +} + +PODTestSuite.test("ClassHoldingPair") { + var x = ClassHoldingPair(pair: IntPair.create()) + expectEqual(x.pair.test(), 1) + expectEqual(x.pair.testMutable(), 1) + + mutateIt(x.pair) + expectEqual(x.pair.test(), 2) + expectEqual(x.pair.testMutable(), 2) + + x.pair = IntPair.create() + expectEqual(x.pair.test(), 1) +} + +PODTestSuite.test("BigType") { + var x = BigType.create() + expectEqual(x.test(), 1) + expectEqual(x.testMutable(), 1) + + mutateIt(x) + expectEqual(x.test(), 2) + expectEqual(x.testMutable(), 2) + + x.b = 42 + expectEqual(x.test(), 40) + expectEqual(x.testMutable(), 40) + + x = BigType.create() + expectEqual(x.test(), 1) +} + +runAllTests() diff --git a/test/Interop/Cxx/foreign-reference/singleton-irgen.swift b/test/Interop/Cxx/foreign-reference/singleton-irgen.swift new file mode 100644 index 0000000000000..505571a9b1e05 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/singleton-irgen.swift @@ -0,0 +1,32 @@ +// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop -validate-tbd-against-ir=none -disable-llvm-verify | %FileCheck %s + +import Singleton + +// TODO: this should not be opaque. +// CHECK: %TSo21DeletedSpecialMembersV = type opaque +// CHECK: %struct.DeletedSpecialMembers = type { i32 } + +// CHECK-LABEL: define swiftcc void @"$s4main4testyyF" + +// CHECK: [[X:%.*]] = alloca %TSo21DeletedSpecialMembersV* +// CHECK: [[TMP:%.*]] = alloca %TSo21DeletedSpecialMembersV* + +// CHECK: [[CREATED:%.*]] = call %struct.DeletedSpecialMembers* @_ZN21DeletedSpecialMembers6createEv() +// CHECK: [[SWIFT_CREATED:%.*]] = bitcast %struct.DeletedSpecialMembers* [[CREATED]] to %TSo21DeletedSpecialMembersV* +// CHECK: store %TSo21DeletedSpecialMembersV* [[SWIFT_CREATED]], %TSo21DeletedSpecialMembersV** [[X]] +// CHECK: store %TSo21DeletedSpecialMembersV* [[SWIFT_CREATED]], %TSo21DeletedSpecialMembersV** [[TMP]] + +// CHECK: [[TMP_LOAD:%.*]] = load %TSo21DeletedSpecialMembersV*, %TSo21DeletedSpecialMembersV** [[TMP]] +// CHECK: [[CLANG_CREATED:%.*]] = bitcast %TSo21DeletedSpecialMembersV* [[TMP_LOAD]] to %struct.DeletedSpecialMembers* +// CHECK: call i32 @_ZNK21DeletedSpecialMembers4testEv(%struct.DeletedSpecialMembers* [[CLANG_CREATED]]) + +// CHECK: [[FROM:%.*]] = bitcast %TSo21DeletedSpecialMembersV* [[SWIFT_CREATED]] to %struct.DeletedSpecialMembers* +// CHECK: call void @_Z8mutateItR21DeletedSpecialMembers(%struct.DeletedSpecialMembers* [[FROM]]) + +// CHECK: ret void + +public func test() { + var x = DeletedSpecialMembers.create() + _ = x.test() + mutateIt(x) +} diff --git a/test/Interop/Cxx/foreign-reference/singleton-module-interface.swift b/test/Interop/Cxx/foreign-reference/singleton-module-interface.swift new file mode 100644 index 0000000000000..ecc20ad59950f --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/singleton-module-interface.swift @@ -0,0 +1,34 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=Singleton -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s + +// CHECK-NOT: init +// CHECK: class DeletedDtor { +// CHECK: var value: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> DeletedDtor +// CHECK: } +// CHECK: func mutateIt(_ x: DeletedDtor) + +// CHECK: class PrivateDtor { +// CHECK: var value: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> PrivateDtor +// CHECK: } +// CHECK: func mutateIt(_ x: PrivateDtor) + +// CHECK: class DeletedSpecialMembers { +// CHECK: var value: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> DeletedSpecialMembers +// CHECK: } +// CHECK: func mutateIt(_ x: DeletedSpecialMembers) + +// CHECK: class PrivateSpecialMembers { +// CHECK: var value: Int32 +// CHECK: func test() -> Int32 +// CHECK: func testMutable() -> Int32 +// CHECK: class func create() -> PrivateSpecialMembers +// CHECK: } +// CHECK: func mutateIt(_ x: PrivateSpecialMembers) diff --git a/test/Interop/Cxx/foreign-reference/singleton-silgen.swift b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift new file mode 100644 index 0000000000000..d8ed5cc2b5b94 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift @@ -0,0 +1,41 @@ +// RUN: %target-swift-emit-silgen %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s + +import Singleton + +// CHECK-NOT: borrow +// CHECK-NOT: retain +// CHECK-NOT: release +// CHECK-LABEL: sil [ossa] @$s4main4testyyF : $@convention(thin) () -> () + +// CHECK: [[BOX:%.*]] = project_box {{.*}} : ${ var DeletedSpecialMembers }, 0 + +// CHECK: [[CREATE_FN:%.*]] = function_ref @_ZN21DeletedSpecialMembers6createEv : $@convention(c) () -> DeletedSpecialMembers +// CHECK: [[CREATED_PTR:%.*]] = apply [[CREATE_FN]]() : $@convention(c) () -> DeletedSpecialMembers +// CHECK: store [[CREATED_PTR]] to [trivial] [[BOX]] : $*DeletedSpecialMembers +// CHECK: [[ACCESS_1:%.*]] = begin_access [read] [unknown] [[BOX]] : $*DeletedSpecialMembers +// CHECK: [[X_1:%.*]] = load [trivial] [[ACCESS_1]] : $*DeletedSpecialMembers + +// CHECK: [[TMP:%.*]] = alloc_stack $DeletedSpecialMembers +// CHECK: store [[X_1]] to [trivial] [[TMP]] + +// CHECK: [[TEST_FN:%.*]] = function_ref @_ZNK21DeletedSpecialMembers4testEv : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 +// CHECK: [[ACCESS_2:%.*]] = begin_access [read] [unknown] [[BOX]] : $*DeletedSpecialMembers +// CHECK: [[X_2:%.*]] = load [trivial] [[ACCESS_2]] : $*DeletedSpecialMembers + +// CHECK: [[MOVE_IN_RES_FN:%.*]] = function_ref @_Z8mutateItR21DeletedSpecialMembers : $@convention(c) (DeletedSpecialMembers) -> () +// CHECK: apply [[MOVE_IN_RES_FN]]([[X_2]]) : $@convention(c) (DeletedSpecialMembers) -> () + +// CHECK: return +// CHECK-LABEL: end sil function '$s4main4testyyF' +public func test() { + var x = DeletedSpecialMembers.create() + _ = x.test() + mutateIt(x) +} + +// CHECK-LABEL: sil [clang DeletedSpecialMembers.create] @_ZN21DeletedSpecialMembers6createEv : $@convention(c) () -> DeletedSpecialMembers + +// CHECK-LABEL: sil [clang DeletedSpecialMembers.test] @_ZNK21DeletedSpecialMembers4testEv : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 + +// CHECK-LABEL: sil [serializable] [clang mutateIt] @_Z8mutateItR21DeletedSpecialMembers : $@convention(c) (DeletedSpecialMembers) -> () diff --git a/test/Interop/Cxx/foreign-reference/singleton.swift b/test/Interop/Cxx/foreign-reference/singleton.swift new file mode 100644 index 0000000000000..3902c73f47ee9 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/singleton.swift @@ -0,0 +1,74 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify) +// +// REQUIRES: executable_test + +import StdlibUnittest +import Singleton + +var SingletonTestSuite = TestSuite("Singleton types that are marked as foreign references") + +SingletonTestSuite.test("DeletedDtor") { + var x = DeletedDtor.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + mutateIt(x) + expectEqual(x.test(), 32) + + x = DeletedDtor.create() + expectEqual(x.test(), 42) + + x.value = 22 + expectEqual(x.value, 22) + expectEqual(x.test(), 22) +} + +SingletonTestSuite.test("PrivateDtor") { + var x = PrivateDtor.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + mutateIt(x) + expectEqual(x.test(), 32) + + x = PrivateDtor.create() + expectEqual(x.test(), 42) + + x.value = 22 + expectEqual(x.value, 22) + expectEqual(x.test(), 22) +} + +SingletonTestSuite.test("DeletedSpecialMembers") { + var x = DeletedSpecialMembers.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + mutateIt(x) + expectEqual(x.test(), 32) + + x = DeletedSpecialMembers.create() + expectEqual(x.test(), 42) + + x.value = 22 + expectEqual(x.value, 22) + expectEqual(x.test(), 22) +} + +SingletonTestSuite.test("PrivateSpecialMembers") { + var x = PrivateSpecialMembers.create() + expectEqual(x.test(), 42) + expectEqual(x.testMutable(), 42) + + mutateIt(x) + expectEqual(x.test(), 32) + + x = PrivateSpecialMembers.create() + expectEqual(x.test(), 42) + + x.value = 22 + expectEqual(x.value, 22) + expectEqual(x.test(), 22) +} + +runAllTests() diff --git a/test/Interop/Cxx/foreign-reference/witness-table.swift b/test/Interop/Cxx/foreign-reference/witness-table.swift new file mode 100644 index 0000000000000..9638db7146566 --- /dev/null +++ b/test/Interop/Cxx/foreign-reference/witness-table.swift @@ -0,0 +1,56 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify -g) +// +// REQUIRES: executable_test + +import StdlibUnittest +import WitnessTable + +public protocol ListNode { + associatedtype Element + func next() -> Element? +} + +public struct List : Sequence, IteratorProtocol + where NodeType.Element == NodeType { + private var currentNode: NodeType? + + public init(startingAt start: NodeType?) { currentNode = start } + + public mutating func next() -> NodeType? { + if let node = currentNode { + currentNode = node.next() + return node + } + return nil + } +} + +extension CxxLinkedList : ListNode { } + +var WitnessTableTestSuite = TestSuite("Use foreign reference in a generic context") + +WitnessTableTestSuite.test("As generic argument to List") { + let first = makeLinkedList() + let list = List(startingAt: first) + var count = 0 + for e in list { + expectEqual(count, Int(e.value)) + count += 1 + } + expectEqual(count, 4) +} + +extension CxxSequence : Sequence, IteratorProtocol { } + +WitnessTableTestSuite.test("As a Sequence") { + let list = makeSequence() + var count = 0 + for e in list { + expectEqual(count, Int(e.value)) + count += 1 + } + expectEqual(count, 3) +} + +runAllTests() + diff --git a/utils/build-script-impl b/utils/build-script-impl index 0d416f0e3cd5b..ffa77af308b9b 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -2746,11 +2746,7 @@ for host in "${ALL_HOSTS[@]}"; do CLANG_BIN="$(build_directory_bin ${LOCAL_HOST} llvm)" fi - if [[ "${NATIVE_SWIFT_TOOLS_PATH}" ]] ; then - SWIFTC_BIN="${NATIVE_SWIFT_TOOLS_PATH}/swiftc" - else - SWIFTC_BIN="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc" - fi + SWIFTC_BIN="/Users/zoecarver/Developer/swift-source/build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc" # Run the tests for each product for product in "${PRODUCTS[@]}"; do