mirror of
https://github.com/apple/swift.git
synced 2026-06-27 12:25:55 +02:00
Merge pull request #19151 from jckarter/allocating-convenience-initializers
Dispatch initializers by their allocating entry point
This commit is contained in:
@@ -6482,9 +6482,8 @@ public:
|
||||
|
||||
static MissingMemberDecl *
|
||||
forInitializer(ASTContext &ctx, DeclContext *DC, DeclName name,
|
||||
bool hasNormalVTableEntry,
|
||||
bool hasAllocatingVTableEntry) {
|
||||
unsigned entries = hasNormalVTableEntry + hasAllocatingVTableEntry;
|
||||
bool hasVTableEntry) {
|
||||
unsigned entries = hasVTableEntry ? 1 : 0;
|
||||
return new (ctx) MissingMemberDecl(DC, name, entries, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,17 +93,12 @@ template <class T> class SILVTableVisitor {
|
||||
void maybeAddConstructor(ConstructorDecl *cd) {
|
||||
assert(!cd->hasClangNode());
|
||||
|
||||
// Required constructors (or overrides thereof) have their allocating entry
|
||||
// point in the vtable.
|
||||
if (cd->isRequired()) {
|
||||
SILDeclRef constant(cd, SILDeclRef::Kind::Allocator);
|
||||
maybeAddEntry(constant, constant.requiresNewVTableEntry());
|
||||
}
|
||||
|
||||
// All constructors have their initializing constructor in the
|
||||
// vtable, which can be used by a convenience initializer.
|
||||
SILDeclRef constant(cd, SILDeclRef::Kind::Initializer);
|
||||
maybeAddEntry(constant, constant.requiresNewVTableEntry());
|
||||
// The allocating entry point is what is used for dynamic dispatch.
|
||||
// The initializing entry point for designated initializers is only
|
||||
// necessary for super.init chaining, which is sufficiently constrained
|
||||
// to never need dynamic dispatch.
|
||||
SILDeclRef constant(cd, SILDeclRef::Kind::Allocator);
|
||||
maybeAddEntry(constant, constant.requiresNewVTableEntry());
|
||||
}
|
||||
|
||||
void maybeAddEntry(SILDeclRef declRef, bool needsNewEntry) {
|
||||
|
||||
@@ -5253,6 +5253,18 @@ static bool requiresNewVTableEntry(const AbstractFunctionDecl *decl) {
|
||||
// Dynamic methods are always accessed by objc_msgSend().
|
||||
if (decl->isFinal() || decl->isDynamic() || decl->hasClangNode())
|
||||
return false;
|
||||
|
||||
// Initializers are not normally inherited, but required initializers can
|
||||
// be overridden for invocation from dynamic types, and convenience initializers
|
||||
// are conditionally inherited when all designated initializers are available,
|
||||
// working by dynamically invoking the designated initializer implementation
|
||||
// from the subclass. Convenience initializers can also override designated
|
||||
// initializer implementations from their superclass.
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
|
||||
if (!ctor->isRequired() && !ctor->isDesignatedInit()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
|
||||
// Check to see if it's one of the opaque accessors for the declaration.
|
||||
@@ -5264,6 +5276,16 @@ static bool requiresNewVTableEntry(const AbstractFunctionDecl *decl) {
|
||||
auto base = decl->getOverriddenDecl();
|
||||
if (!base || base->hasClangNode() || base->isDynamic())
|
||||
return true;
|
||||
|
||||
// As above, convenience initializers are not formally overridable in Swift
|
||||
// vtables, although same-named initializers are modeled as overriding for
|
||||
// various QoI and objc interop reasons. Even if we "override" a non-required
|
||||
// convenience init, we still need a distinct vtable entry.
|
||||
if (auto baseCtor = dyn_cast<ConstructorDecl>(base)) {
|
||||
if (!baseCtor->isRequired() && !baseCtor->isDesignatedInit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the method overrides something, we only need a new entry if the
|
||||
// override has a more general AST type. However an abstraction
|
||||
|
||||
+34
-20
@@ -48,13 +48,21 @@ swift::getMethodDispatch(AbstractFunctionDecl *method) {
|
||||
if (method->isFinal())
|
||||
return MethodDispatch::Static;
|
||||
|
||||
// Members defined directly inside a class are dynamically dispatched.
|
||||
if (isa<ClassDecl>(dc))
|
||||
return MethodDispatch::Class;
|
||||
|
||||
// Imported class methods are dynamically dispatched.
|
||||
if (method->isObjC() && method->hasClangNode())
|
||||
return MethodDispatch::Class;
|
||||
|
||||
// Members defined directly inside a class are dynamically dispatched.
|
||||
if (isa<ClassDecl>(dc)) {
|
||||
// Native convenience initializers are not dynamically dispatched unless
|
||||
// required.
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(method)) {
|
||||
if (!ctor->isRequired() && !ctor->isDesignatedInit()
|
||||
&& !requiresForeignEntryPoint(ctor))
|
||||
return MethodDispatch::Static;
|
||||
}
|
||||
return MethodDispatch::Class;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, it can be referenced statically.
|
||||
@@ -715,16 +723,6 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
|
||||
bool SILDeclRef::requiresNewVTableEntry() const {
|
||||
if (cast<AbstractFunctionDecl>(getDecl())->needsNewVTableEntry())
|
||||
return true;
|
||||
if (kind == SILDeclRef::Kind::Allocator) {
|
||||
auto *cd = cast<ConstructorDecl>(getDecl());
|
||||
if (cd->isRequired()) {
|
||||
auto *baseCD = cd->getOverriddenDecl();
|
||||
if(!baseCD ||
|
||||
!baseCD->isRequired() ||
|
||||
baseCD->hasClangNode())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -748,18 +746,34 @@ SILDeclRef SILDeclRef::getOverridden() const {
|
||||
|
||||
SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const {
|
||||
if (auto overridden = getOverridden()) {
|
||||
// If we overrode a foreign decl, a dynamic method, this is an
|
||||
// If we overrode a foreign decl or dynamic method, if this is an
|
||||
// accessor for a property that overrides an ObjC decl, or if it is an
|
||||
// @NSManaged property, then it won't be in the vtable.
|
||||
if (overridden.getDecl()->hasClangNode())
|
||||
return SILDeclRef();
|
||||
|
||||
// If we overrode a non-required initializer, there won't be a vtable
|
||||
// slot for the allocator.
|
||||
|
||||
// An @objc convenience initializer can be "overridden" in the sense that
|
||||
// its selector is reclaimed by a subclass's convenience init with the
|
||||
// same name. The AST models this as an override for the purposes of
|
||||
// ObjC selector validation, but it isn't for Swift method dispatch
|
||||
// purposes.
|
||||
if (overridden.kind == SILDeclRef::Kind::Allocator) {
|
||||
if (!cast<ConstructorDecl>(overridden.getDecl())->isRequired())
|
||||
auto overriddenCtor = cast<ConstructorDecl>(overridden.getDecl());
|
||||
if (!overriddenCtor->isDesignatedInit()
|
||||
&& !overriddenCtor->isRequired())
|
||||
return SILDeclRef();
|
||||
} else if (overridden.getDecl()->isDynamic()) {
|
||||
}
|
||||
|
||||
// Initializing entry points for initializers won't be in the vtable.
|
||||
// For Swift designated initializers, they're only used in super.init
|
||||
// chains, which can always be statically resolved. Other native Swift
|
||||
// initializers only have allocating entry points. ObjC initializers always
|
||||
// have the initializing entry point (corresponding to the -init method)
|
||||
// but those are never in the vtable.
|
||||
if (overridden.kind == SILDeclRef::Kind::Initializer) {
|
||||
return SILDeclRef();
|
||||
}
|
||||
if (overridden.getDecl()->isDynamic()) {
|
||||
return SILDeclRef();
|
||||
}
|
||||
|
||||
|
||||
+44
-24
@@ -757,9 +757,7 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
|
||||
|
||||
bool ForCoverageMapping = doesASTRequireProfiling(M, decl);
|
||||
|
||||
if (declCtx->getSelfClassDecl()) {
|
||||
// Class constructors have separate entry points for allocation and
|
||||
// initialization.
|
||||
auto emitClassAllocatorThunk = [&]{
|
||||
emitOrDelayFunction(
|
||||
*this, constant, [this, constant, decl](SILFunction *f) {
|
||||
preEmitFunction(constant, decl, f, decl);
|
||||
@@ -767,27 +765,8 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
|
||||
SILGenFunction(*this, *f, decl).emitClassConstructorAllocator(decl);
|
||||
postEmitFunction(constant, f);
|
||||
});
|
||||
|
||||
// Constructors may not have bodies if they've been imported, or if they've
|
||||
// been parsed from a textual interface.
|
||||
if (decl->hasBody()) {
|
||||
SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
|
||||
emitOrDelayFunction(
|
||||
*this, initConstant,
|
||||
[this, initConstant, decl, declCtx](SILFunction *initF) {
|
||||
preEmitFunction(initConstant, decl, initF, decl);
|
||||
PrettyStackTraceSILFunction X("silgen constructor initializer",
|
||||
initF);
|
||||
initF->setProfiler(
|
||||
getOrCreateProfilerForConstructors(declCtx, decl));
|
||||
SILGenFunction(*this, *initF, decl)
|
||||
.emitClassConstructorInitializer(decl);
|
||||
postEmitFunction(initConstant, initF);
|
||||
},
|
||||
/*forceEmission=*/ForCoverageMapping);
|
||||
}
|
||||
} else {
|
||||
// Struct and enum constructors do everything in a single function.
|
||||
};
|
||||
auto emitValueConstructorIfHasBody = [&]{
|
||||
if (decl->hasBody()) {
|
||||
emitOrDelayFunction(
|
||||
*this, constant, [this, constant, decl, declCtx](SILFunction *f) {
|
||||
@@ -798,6 +777,47 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
|
||||
postEmitFunction(constant, f);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (declCtx->getSelfClassDecl()) {
|
||||
// Designated initializers for classes have have separate entry points for
|
||||
// allocation and initialization.
|
||||
if (decl->isDesignatedInit()) {
|
||||
emitClassAllocatorThunk();
|
||||
|
||||
// Constructors may not have bodies if they've been imported, or if they've
|
||||
// been parsed from a textual interface.
|
||||
if (decl->hasBody()) {
|
||||
SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
|
||||
emitOrDelayFunction(
|
||||
*this, initConstant,
|
||||
[this, initConstant, decl, declCtx](SILFunction *initF) {
|
||||
preEmitFunction(initConstant, decl, initF, decl);
|
||||
PrettyStackTraceSILFunction X("silgen constructor initializer",
|
||||
initF);
|
||||
initF->setProfiler(
|
||||
getOrCreateProfilerForConstructors(declCtx, decl));
|
||||
SILGenFunction(*this, *initF, decl)
|
||||
.emitClassConstructorInitializer(decl);
|
||||
postEmitFunction(initConstant, initF);
|
||||
},
|
||||
/*forceEmission=*/ForCoverageMapping);
|
||||
}
|
||||
// Convenience initializers for classes behave more like value constructors
|
||||
// in that there's only an allocating entry point that effectively
|
||||
// "constructs" the self reference by invoking another initializer.
|
||||
} else {
|
||||
emitValueConstructorIfHasBody();
|
||||
|
||||
// If the convenience initializer was imported from ObjC, we still have to
|
||||
// emit the allocator thunk.
|
||||
if (decl->hasClangNode()) {
|
||||
emitClassAllocatorThunk();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Struct and enum constructors do everything in a single function.
|
||||
emitValueConstructorIfHasBody();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+125
-67
@@ -142,6 +142,12 @@ static bool canUseStaticDispatch(SILGenFunction &SGF,
|
||||
|
||||
if (funcDecl->isFinal())
|
||||
return true;
|
||||
|
||||
// Native initializing entry points are always statically dispatched.
|
||||
if (constant.kind == SILDeclRef::Kind::Initializer
|
||||
&& !constant.isForeign)
|
||||
return true;
|
||||
|
||||
// Extension methods currently must be statically dispatched, unless they're
|
||||
// @objc or dynamic.
|
||||
if (funcDecl->getDeclContext()->isExtensionContext()
|
||||
@@ -834,30 +840,64 @@ public:
|
||||
visit(e->getFn());
|
||||
}
|
||||
|
||||
/// Idempotently convert a metatype to an objc metatype.
|
||||
std::pair<ManagedValue, SILType> convertToObjCMetatype(ManagedValue selfMeta,
|
||||
SILLocation loc) {
|
||||
auto metaType = selfMeta.getType().castTo<AnyMetatypeType>();
|
||||
CanType instanceType = metaType.getInstanceType();
|
||||
static constexpr unsigned metatypeRepPair(MetatypeRepresentation a,
|
||||
MetatypeRepresentation b) {
|
||||
return assert(unsigned(a) < 256 && unsigned(b) < 256
|
||||
&& "MetatypeRepresentation got too big for its britches"),
|
||||
unsigned(a) << 8 | unsigned(b);
|
||||
}
|
||||
|
||||
// If we are already objc, just return.
|
||||
if (metaType->getRepresentation() == MetatypeRepresentation::ObjC) {
|
||||
/// Idempotently convert a metatype to a thick or objc metatype, depending
|
||||
/// on what allocation mechanism we need for a given class hierarchy.
|
||||
std::pair<ManagedValue, SILType>
|
||||
convertToMetatypeForAllocRefDynamic(ManagedValue selfMeta,
|
||||
SILLocation loc,
|
||||
bool usesObjCAllocation) {
|
||||
auto givenMetatype = selfMeta.getType().castTo<AnyMetatypeType>();
|
||||
CanType instanceType = givenMetatype.getInstanceType();
|
||||
|
||||
auto destMetatypeRep = usesObjCAllocation
|
||||
? MetatypeRepresentation::ObjC
|
||||
: MetatypeRepresentation::Thick;
|
||||
|
||||
// If we are already the right rep, just return.
|
||||
auto givenMetatypeRep = givenMetatype->getRepresentation();
|
||||
if (givenMetatypeRep == destMetatypeRep) {
|
||||
return {selfMeta, SGF.SGM.getLoweredType(instanceType)};
|
||||
}
|
||||
|
||||
CanAnyMetatypeType objcMetaType;
|
||||
if (isa<MetatypeType>(metaType)) {
|
||||
objcMetaType =
|
||||
CanMetatypeType::get(instanceType, MetatypeRepresentation::ObjC);
|
||||
CanAnyMetatypeType destMetatype;
|
||||
if (isa<MetatypeType>(givenMetatype)) {
|
||||
destMetatype =
|
||||
CanMetatypeType::get(instanceType, destMetatypeRep);
|
||||
} else {
|
||||
objcMetaType = CanExistentialMetatypeType::get(
|
||||
instanceType, MetatypeRepresentation::ObjC);
|
||||
destMetatype = CanExistentialMetatypeType::get(instanceType,
|
||||
destMetatypeRep);
|
||||
}
|
||||
// ObjC metatypes are trivial and thus do not have a cleanup. Only if we
|
||||
// Metatypes are trivial and thus do not have a cleanup. Only if we
|
||||
// convert them to an object do they become non-trivial.
|
||||
assert(!selfMeta.hasCleanup());
|
||||
auto result = ManagedValue::forUnmanaged(SGF.B.emitThickToObjCMetatype(
|
||||
loc, selfMeta.getValue(), SGF.SGM.getLoweredType(objcMetaType)));
|
||||
SILValue convertedValue;
|
||||
switch (metatypeRepPair(givenMetatypeRep, destMetatypeRep)) {
|
||||
case metatypeRepPair(MetatypeRepresentation::Thick,
|
||||
MetatypeRepresentation::ObjC):
|
||||
convertedValue = SGF.B.emitThickToObjCMetatype(
|
||||
loc, selfMeta.getValue(),
|
||||
SILType::getPrimitiveObjectType(destMetatype));
|
||||
break;
|
||||
|
||||
case metatypeRepPair(MetatypeRepresentation::ObjC,
|
||||
MetatypeRepresentation::Thick):
|
||||
convertedValue = SGF.B.emitObjCToThickMetatype(
|
||||
loc, selfMeta.getValue(),
|
||||
SILType::getPrimitiveObjectType(destMetatype));
|
||||
break;
|
||||
|
||||
default:
|
||||
llvm_unreachable("shouldn't happen");
|
||||
}
|
||||
|
||||
auto result = ManagedValue::forUnmanaged(convertedValue);
|
||||
return {result, SGF.SGM.getLoweredType(instanceType)};
|
||||
}
|
||||
|
||||
@@ -865,15 +905,18 @@ public:
|
||||
/// object (with alloc_ref_dynamic) of that type.
|
||||
///
|
||||
/// \returns the self object.
|
||||
ManagedValue allocateObjCObject(ManagedValue selfMeta, SILLocation loc) {
|
||||
// Convert to an Objective-C metatype representation, if needed.
|
||||
ManagedValue selfMetaObjC;
|
||||
ManagedValue allocateObject(ManagedValue selfMeta,
|
||||
SILLocation loc,
|
||||
bool usesObjCAllocation) {
|
||||
// Convert to the necessary metatype representation, if needed.
|
||||
ManagedValue selfMetaConverted;
|
||||
SILType instanceType;
|
||||
std::tie(selfMetaObjC, instanceType) = convertToObjCMetatype(selfMeta, loc);
|
||||
std::tie(selfMetaConverted, instanceType) =
|
||||
convertToMetatypeForAllocRefDynamic(selfMeta, loc, usesObjCAllocation);
|
||||
|
||||
// Allocate the object.
|
||||
return SGF.B.createAllocRefDynamic(loc, selfMetaObjC, instanceType,
|
||||
/*objc=*/true, {}, {});
|
||||
return SGF.B.createAllocRefDynamic(loc, selfMetaConverted, instanceType,
|
||||
usesObjCAllocation, {}, {});
|
||||
}
|
||||
|
||||
void processProtocolMethod(DeclRefExpr *e, AbstractFunctionDecl *afd,
|
||||
@@ -896,7 +939,7 @@ public:
|
||||
kind = SILDeclRef::Kind::Initializer;
|
||||
|
||||
auto metatype = std::move(selfValue).getAsSingleValue(SGF);
|
||||
auto allocated = allocateObjCObject(metatype, loc);
|
||||
auto allocated = allocateObject(metatype, loc, /*objc*/ true);
|
||||
auto allocatedType = allocated.getType().getASTType();
|
||||
selfValue =
|
||||
ArgumentSource(loc, RValue(SGF, loc, allocatedType, allocated));
|
||||
@@ -969,7 +1012,8 @@ public:
|
||||
SILLocation loc = thisCallSite->getArg();
|
||||
RValue selfMetatype = SGF.emitRValue(thisCallSite->getArg());
|
||||
auto selfValue =
|
||||
allocateObjCObject(std::move(selfMetatype).getAsSingleValue(SGF, loc), loc);
|
||||
allocateObject(std::move(selfMetatype).getAsSingleValue(SGF, loc),
|
||||
loc, /*objc*/ true);
|
||||
RValue self = RValue(SGF, loc, selfValue.getType().getASTType(),
|
||||
selfValue);
|
||||
ArgumentSource selfArgSource(thisCallSite->getArg(), std::move(self));
|
||||
@@ -1188,38 +1232,27 @@ public:
|
||||
/// subset of expressions used there.
|
||||
ManagedValue emitCorrespondingSelfValue(ManagedValue selfValue,
|
||||
Expr *selfArg) {
|
||||
SILLocation loc = selfArg;
|
||||
auto resultTy = selfArg->getType()->getCanonicalType();
|
||||
while (true) {
|
||||
// Handle archetype-to-super and derived-to-base upcasts.
|
||||
if (isa<ArchetypeToSuperExpr>(selfArg) ||
|
||||
isa<DerivedToBaseExpr>(selfArg)) {
|
||||
auto ice = cast<ImplicitConversionExpr>(selfArg);
|
||||
auto resultTy = ice->getType()->getCanonicalType();
|
||||
|
||||
// If the 'self' value is a metatype, update the target type
|
||||
// accordingly.
|
||||
if (auto selfMetaTy = selfValue.getType().getAs<AnyMetatypeType>()) {
|
||||
resultTy = CanMetatypeType::get(resultTy,
|
||||
selfMetaTy->getRepresentation());
|
||||
}
|
||||
auto loweredResultTy = SGF.getLoweredLoadableType(resultTy);
|
||||
if (loweredResultTy != selfValue.getType()) {
|
||||
selfValue = SGF.emitManagedRValueWithCleanup(
|
||||
SGF.B.createUpcast(ice, selfValue.forward(SGF), loweredResultTy));
|
||||
}
|
||||
|
||||
selfArg = ice->getSubExpr();
|
||||
selfArg = cast<ImplicitConversionExpr>(selfArg)->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip over loads.
|
||||
if (auto load = dyn_cast<LoadExpr>(selfArg)) {
|
||||
selfArg = load->getSubExpr();
|
||||
resultTy = resultTy->getRValueType()->getCanonicalType();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip over inout expressions.
|
||||
if (auto inout = dyn_cast<InOutExpr>(selfArg)) {
|
||||
selfArg = inout->getSubExpr();
|
||||
resultTy = resultTy->getInOutObjectType()->getCanonicalType();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1229,7 +1262,37 @@ public:
|
||||
|
||||
llvm_unreachable("unhandled conversion for metatype value");
|
||||
}
|
||||
|
||||
assert(isa<DeclRefExpr>(selfArg) &&
|
||||
"unexpected expr kind in self argument of initializer delegation");
|
||||
|
||||
// If the 'self' value is a metatype, update the target type
|
||||
// accordingly.
|
||||
SILType loweredResultTy;
|
||||
auto selfMetaTy = selfValue.getType().getAs<AnyMetatypeType>();
|
||||
if (selfMetaTy) {
|
||||
loweredResultTy = SILType::getPrimitiveObjectType(
|
||||
CanMetatypeType::get(resultTy, selfMetaTy->getRepresentation()));
|
||||
} else {
|
||||
loweredResultTy = SGF.getLoweredLoadableType(resultTy);
|
||||
}
|
||||
|
||||
if (loweredResultTy != selfValue.getType()) {
|
||||
// Introduce dynamic Self if necessary. A class initializer receives
|
||||
// a metatype argument that's formally the non-dynamic base class type
|
||||
// (though always dynamically of Self type),
|
||||
// but when invoking a protocol initializer, we need to pass it as
|
||||
// dynamic Self.
|
||||
if (!selfValue.getType().getASTType()->hasDynamicSelfType()
|
||||
&& loweredResultTy.getASTType()->hasDynamicSelfType()) {
|
||||
assert(selfMetaTy);
|
||||
selfValue = SGF.emitManagedRValueWithCleanup(
|
||||
SGF.B.createUncheckedBitCast(loc, selfValue.forward(SGF),
|
||||
loweredResultTy));
|
||||
} else {
|
||||
selfValue = SGF.emitManagedRValueWithCleanup(
|
||||
SGF.B.createUpcast(loc, selfValue.forward(SGF), loweredResultTy));
|
||||
}
|
||||
}
|
||||
return selfValue;
|
||||
}
|
||||
|
||||
@@ -1255,19 +1318,14 @@ public:
|
||||
// protocols, which only witness initializing initializers.
|
||||
else if (auto proto = dyn_cast<ProtocolDecl>(nominal)) {
|
||||
useAllocatingCtor = !proto->isObjC();
|
||||
// Factory initializers are effectively "allocating" initializers with no
|
||||
// corresponding initializing entry point.
|
||||
} else if (ctorRef->getDecl()->isFactoryInit()) {
|
||||
useAllocatingCtor = true;
|
||||
// Similarly, class initializers self.init-delegate to each other via
|
||||
// their allocating entry points, unless delegating to an ObjC-only,
|
||||
// non-factory initializer.
|
||||
} else {
|
||||
// We've established we're in a class initializer or a protocol extension
|
||||
// initializer for a class-bound protocol, In either case, we're
|
||||
// delegating initialization, but we only have an instance in the former
|
||||
// case.
|
||||
assert(isa<ClassDecl>(nominal)
|
||||
&& "some new kind of init context we haven't implemented");
|
||||
useAllocatingCtor = static_cast<bool>(SGF.AllocatorMetatype) &&
|
||||
!ctorRef->getDecl()->isObjC();
|
||||
useAllocatingCtor = ctorRef->getDecl()->isFactoryInit()
|
||||
|| !requiresForeignEntryPoint(ctorRef->getDecl());
|
||||
}
|
||||
|
||||
// Load the 'self' argument.
|
||||
@@ -1292,16 +1350,20 @@ public:
|
||||
self = ManagedValue::forUnmanaged(SGF.emitMetatypeOfValue(expr, arg));
|
||||
}
|
||||
} else {
|
||||
// If we're in a protocol extension initializer, we haven't allocated
|
||||
// "self" yet at this point. Do so. Use alloc_ref_dynamic since we should
|
||||
// only ever get here in ObjC protocol extensions currently.
|
||||
// If we haven't allocated "self" yet at this point, do so.
|
||||
if (SGF.AllocatorMetatype) {
|
||||
assert(ctorRef->getDecl()->isObjC()
|
||||
&& "only expect to delegate an initializer from an allocator "
|
||||
"in objc protocol extensions");
|
||||
bool usesObjCAllocation;
|
||||
if (auto clas = dyn_cast<ClassDecl>(nominal)) {
|
||||
usesObjCAllocation = usesObjCAllocator(clas);
|
||||
} else {
|
||||
// In the protocol extension case, we should only be here if the callee
|
||||
// initializer is @objc.
|
||||
usesObjCAllocation = true;
|
||||
}
|
||||
|
||||
self = allocateObjCObject(
|
||||
ManagedValue::forUnmanaged(SGF.AllocatorMetatype), arg);
|
||||
self = allocateObject(
|
||||
ManagedValue::forUnmanaged(SGF.AllocatorMetatype), arg,
|
||||
usesObjCAllocation);
|
||||
|
||||
// Perform any adjustments needed to 'self'.
|
||||
self = emitCorrespondingSelfValue(self, arg);
|
||||
@@ -1325,19 +1387,15 @@ public:
|
||||
|
||||
constant = constant.asForeign(requiresForeignEntryPoint(ctorRef->getDecl()));
|
||||
|
||||
// Determine the callee. For structs and enums, this is the allocating
|
||||
// constructor (because there is no initializing constructor). For protocol
|
||||
// default implementations, we also use the allocating constructor, because
|
||||
// that's the only thing that's witnessed. For classes,
|
||||
// this is the initializing constructor, to which we will dynamically
|
||||
// dispatch.
|
||||
// Determine the callee. This is normally the allocating
|
||||
// entry point, unless we're delegating to an ObjC initializer.
|
||||
if (isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
|
||||
// Look up the witness for the constructor.
|
||||
setCallee(Callee::forWitnessMethod(
|
||||
SGF, self.getType().getASTType(),
|
||||
constant, subs, expr));
|
||||
} else if (getMethodDispatch(ctorRef->getDecl())
|
||||
== MethodDispatch::Class) {
|
||||
} else if ((useAllocatingCtor || constant.isForeign)
|
||||
&& getMethodDispatch(ctorRef->getDecl()) == MethodDispatch::Class) {
|
||||
// Dynamic dispatch to the initializer.
|
||||
Scope S(SGF, expr);
|
||||
setCallee(Callee::forClassMethod(
|
||||
|
||||
@@ -1377,6 +1377,21 @@ static SILFunctionType *emitObjCThunkArguments(SILGenFunction &SGF,
|
||||
void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
|
||||
assert(thunk.isForeign);
|
||||
SILDeclRef native = thunk.asForeign(false);
|
||||
|
||||
// If we're calling a native non-designated class initializer, we have to
|
||||
// discard the `self` object we were given, since
|
||||
// Swift convenience initializers only have allocating entry points that
|
||||
// create whole new objects.
|
||||
bool isInitializingToAllocatingInitThunk = false;
|
||||
if (native.kind == SILDeclRef::Kind::Initializer) {
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(native.getDecl())) {
|
||||
if (!ctor->isDesignatedInit()) {
|
||||
isInitializingToAllocatingInitThunk = true;
|
||||
native = SILDeclRef(ctor, SILDeclRef::Kind::Allocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto nativeInfo = getConstantInfo(native);
|
||||
auto subs = F.getForwardingSubstitutionMap();
|
||||
auto substTy = nativeInfo.SILFnType->substGenericArgs(SGM.M, subs);
|
||||
@@ -1454,6 +1469,24 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
|
||||
foreignErrorSlot, foreignError,
|
||||
nativeFormalResultType,
|
||||
bridgedFormalResultType);
|
||||
|
||||
// Throw away the partially-initialized `self` value we were given if we're
|
||||
// bridging from an initializing to allocating entry point.
|
||||
if (isInitializingToAllocatingInitThunk) {
|
||||
auto oldSelf = args.pop_back_val();
|
||||
auto oldSelfTy = B.createValueMetatype(loc,
|
||||
SILType::getPrimitiveObjectType(
|
||||
CanMetatypeType::get(oldSelf->getType().getASTType(),
|
||||
MetatypeRepresentation::Thick)),
|
||||
oldSelf);
|
||||
|
||||
B.createDeallocPartialRef(loc, oldSelf, oldSelfTy);
|
||||
|
||||
// Pass the dynamic type on to the native allocating initializer.
|
||||
args.push_back(oldSelfTy);
|
||||
native = SILDeclRef(native.getDecl(), SILDeclRef::Kind::Allocator);
|
||||
}
|
||||
|
||||
SILFunctionConventions objcConv(CanSILFunctionType(objcFnTy), SGM.M);
|
||||
SILFunctionConventions nativeConv(CanSILFunctionType(nativeInfo.SILFnType),
|
||||
SGM.M);
|
||||
|
||||
@@ -204,10 +204,6 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
|
||||
// Get the 'self' decl and type.
|
||||
VarDecl *selfDecl = ctor->getImplicitSelfDecl();
|
||||
auto &lowering = getTypeLowering(selfDecl->getType());
|
||||
SILType selfTy = lowering.getLoweredType();
|
||||
(void)selfTy;
|
||||
assert(!selfTy.getClassOrBoundGenericClass()
|
||||
&& "can't emit a class ctor here");
|
||||
|
||||
// Decide if we need to do extra work to warn on unsafe behavior in pre-Swift-5
|
||||
// modes.
|
||||
@@ -485,9 +481,9 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
|
||||
// Allocate the 'self' value.
|
||||
bool useObjCAllocation = usesObjCAllocator(selfClassDecl);
|
||||
|
||||
if (ctor->isConvenienceInit() || ctor->hasClangNode()) {
|
||||
// For a convenience initializer or an initializer synthesized
|
||||
// for an Objective-C class, allocate using the metatype.
|
||||
if (ctor->hasClangNode()) {
|
||||
// For an allocator thunk synthesized for an Objective-C init method,
|
||||
// allocate using the metatype.
|
||||
SILValue allocArg = selfMetaValue;
|
||||
|
||||
// When using Objective-C allocation, convert the metatype
|
||||
@@ -503,6 +499,7 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
|
||||
selfValue = B.createAllocRefDynamic(Loc, allocArg, selfTy,
|
||||
useObjCAllocation, {}, {});
|
||||
} else {
|
||||
assert(ctor->isDesignatedInit());
|
||||
// For a designated initializer, we know that the static type being
|
||||
// allocated is the type of the class that defines the designated
|
||||
// initializer.
|
||||
|
||||
@@ -3579,9 +3579,13 @@ static WitnessDispatchKind getWitnessDispatchKind(SILDeclRef witness) {
|
||||
return WitnessDispatchKind::Static;
|
||||
|
||||
// If the witness is dynamic, go through dynamic dispatch.
|
||||
if (decl->isDynamic()
|
||||
&& witness.kind != SILDeclRef::Kind::Allocator)
|
||||
if (decl->isDynamic()) {
|
||||
// For initializers we still emit a static allocating thunk around
|
||||
// the dynamic initializing entry point.
|
||||
if (witness.kind == SILDeclRef::Kind::Allocator)
|
||||
return WitnessDispatchKind::Static;
|
||||
return WitnessDispatchKind::Dynamic;
|
||||
}
|
||||
|
||||
bool isFinal = (decl->isFinal() || C->isFinal());
|
||||
if (auto fnDecl = dyn_cast<AbstractFunctionDecl>(witness.getDecl()))
|
||||
|
||||
@@ -1476,15 +1476,15 @@ void ElementUseCollector::collectClassSelfUses(
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DelegatingValueTypeInitUseCollector
|
||||
// DelegatingInitUseCollector
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void
|
||||
collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
|
||||
DIElementUseInfo &UseInfo,
|
||||
SingleValueInstruction *I) {
|
||||
collectDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
|
||||
DIElementUseInfo &UseInfo,
|
||||
SingleValueInstruction *I) {
|
||||
for (auto *Op : I->getUses()) {
|
||||
auto *User = Op->getUser();
|
||||
SILInstruction *User = Op->getUser();
|
||||
|
||||
// destroy_addr is a release of the entire value. This can result from an
|
||||
// early release due to a conditional initializer.
|
||||
@@ -1519,13 +1519,48 @@ collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
|
||||
|
||||
// Look through begin_access
|
||||
if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
|
||||
collectValueTypeDelegatingInitUses(TheMemory, UseInfo, BAI);
|
||||
collectDelegatingInitUses(TheMemory, UseInfo, BAI);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore end_access
|
||||
if (isa<EndAccessInst>(User))
|
||||
continue;
|
||||
|
||||
// A load of the value that's only used to handle a type(of:) query before
|
||||
// self has been initialized can just use the initializer's metatype
|
||||
// argument. For value types, there's no metatype subtyping to worry about,
|
||||
// and for class convenience initializers, `self` notionally has the
|
||||
// original Self type as its dynamic type before theoretically being
|
||||
// rebound.
|
||||
//
|
||||
// This is necessary for source compatibility; previously, convenience
|
||||
// initializers behaved like in Objective-C where the initializer received
|
||||
// an uninitialized object to fill in, and type(of: self) worked by asking
|
||||
// for the dynamic type of that uninitialized object.
|
||||
if (isa<LoadInst>(User)) {
|
||||
auto UserVal = cast<SingleValueInstruction>(User);
|
||||
if (UserVal->hasOneUse()
|
||||
&& isa<ValueMetatypeInst>(UserVal->getSingleUse()->get())) {
|
||||
Kind = DIUseKind::LoadForTypeOfSelf;
|
||||
}
|
||||
}
|
||||
// value_metatype may appear on a borrowed load, in which case there'll
|
||||
// be an end_borrow use in addition to the value_metatype.
|
||||
if (isa<LoadBorrowInst>(User)) {
|
||||
auto UserVal = cast<SingleValueInstruction>(User);
|
||||
bool onlyUseIsValueMetatype = true;
|
||||
for (auto use : UserVal->getUses()) {
|
||||
if (isa<EndBorrowInst>(use->getUser())
|
||||
|| isa<ValueMetatypeInst>(use->getUser()))
|
||||
continue;
|
||||
onlyUseIsValueMetatype = false;
|
||||
break;
|
||||
}
|
||||
if (onlyUseIsValueMetatype) {
|
||||
Kind = DIUseKind::LoadForTypeOfSelf;
|
||||
}
|
||||
}
|
||||
|
||||
// We can safely handle anything else as an escape. They should all happen
|
||||
// after self.init is invoked.
|
||||
@@ -1534,17 +1569,17 @@ collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DelegatingClassInitElementUseCollector
|
||||
// ClassInitElementUseCollector
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
|
||||
class DelegatingClassInitElementUseCollector {
|
||||
class ClassInitElementUseCollector {
|
||||
const DIMemoryObjectInfo &TheMemory;
|
||||
DIElementUseInfo &UseInfo;
|
||||
|
||||
public:
|
||||
DelegatingClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
|
||||
ClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
|
||||
DIElementUseInfo &UseInfo)
|
||||
: TheMemory(TheMemory), UseInfo(UseInfo) {}
|
||||
|
||||
@@ -1552,15 +1587,15 @@ public:
|
||||
|
||||
// *NOTE* Even though this takes a SILInstruction it actually only accepts
|
||||
// load_borrow and load instructions. This is enforced via an assert.
|
||||
void collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
|
||||
SingleValueInstruction *LI);
|
||||
void collectClassInitSelfLoadUses(MarkUninitializedInst *MUI,
|
||||
SingleValueInstruction *LI);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// collectDelegatingClassInitSelfUses - Collect uses of the self argument in a
|
||||
/// delegating-constructor-for-a-class case.
|
||||
void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
|
||||
void ClassInitElementUseCollector::collectClassInitSelfUses() {
|
||||
// When we're analyzing a delegating constructor, we aren't field sensitive at
|
||||
// all. Just treat all members of self as uses of the single
|
||||
// non-field-sensitive value.
|
||||
@@ -1668,8 +1703,7 @@ void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
|
||||
|
||||
// Loads of the box produce self, so collect uses from them.
|
||||
if (isa<LoadInst>(User) || isa<LoadBorrowInst>(User)) {
|
||||
collectDelegatingClassInitSelfLoadUses(MUI,
|
||||
cast<SingleValueInstruction>(User));
|
||||
collectClassInitSelfLoadUses(MUI, cast<SingleValueInstruction>(User));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1691,8 +1725,8 @@ void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
|
||||
gatherDestroysOfContainer(MUI, UseInfo);
|
||||
}
|
||||
|
||||
void DelegatingClassInitElementUseCollector::
|
||||
collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
|
||||
void ClassInitElementUseCollector::
|
||||
collectClassInitSelfLoadUses(MarkUninitializedInst *MUI,
|
||||
SingleValueInstruction *LI) {
|
||||
assert(isa<LoadBorrowInst>(LI) || isa<LoadInst>(LI));
|
||||
|
||||
@@ -1775,10 +1809,7 @@ collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static bool shouldPerformClassInitSelf(const DIMemoryObjectInfo &MemoryInfo) {
|
||||
if (MemoryInfo.isDelegatingInit()) {
|
||||
assert(MemoryInfo.isClassInitSelf());
|
||||
return true;
|
||||
}
|
||||
assert(!MemoryInfo.isDelegatingInit());
|
||||
|
||||
return MemoryInfo.isNonDelegatingInit() &&
|
||||
MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
|
||||
@@ -1792,18 +1823,17 @@ void swift::ownership::collectDIElementUsesFrom(
|
||||
const DIMemoryObjectInfo &MemoryInfo, DIElementUseInfo &UseInfo,
|
||||
bool isDIFinished, bool TreatAddressToPointerAsInout) {
|
||||
|
||||
if (MemoryInfo.isDelegatingInit() && !MemoryInfo.isClassInitSelf()) {
|
||||
if (MemoryInfo.isDelegatingInit()) {
|
||||
// When we're analyzing a delegating constructor, we aren't field sensitive
|
||||
// at all. Just treat all members of self as uses of the single
|
||||
// non-field-sensitive value.
|
||||
assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
|
||||
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo,
|
||||
MemoryInfo.MemoryInst);
|
||||
collectDelegatingInitUses(MemoryInfo, UseInfo, MemoryInfo.MemoryInst);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldPerformClassInitSelf(MemoryInfo)) {
|
||||
DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
|
||||
ClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
|
||||
UseCollector.collectClassInitSelfUses();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,8 +116,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// True if the memory object is the 'self' argument of a class initializer.
|
||||
/// True if the memory object is the 'self' argument of a class designated
|
||||
/// initializer.
|
||||
bool isClassInitSelf() const {
|
||||
if (isDelegatingInit())
|
||||
return false;
|
||||
|
||||
if (!MemoryInst->isVar()) {
|
||||
if (auto decl = getType()->getAnyNominal()) {
|
||||
if (isa<ClassDecl>(decl)) {
|
||||
@@ -226,7 +230,11 @@ enum DIUseKind {
|
||||
|
||||
/// This instruction is a call to 'self.init' in a delegating initializer,
|
||||
/// or a call to 'super.init' in a designated initializer of a derived class..
|
||||
SelfInit
|
||||
SelfInit,
|
||||
|
||||
/// This instruction is a load that's only used to answer a `type(of: self)`
|
||||
/// question.
|
||||
LoadForTypeOfSelf,
|
||||
};
|
||||
|
||||
/// This struct represents a single classified access to the memory object
|
||||
|
||||
@@ -480,6 +480,7 @@ namespace {
|
||||
|
||||
void handleStoreUse(unsigned UseID);
|
||||
void handleLoadUse(unsigned UseID);
|
||||
void handleLoadForTypeOfSelfUse(const DIMemoryUse &Use);
|
||||
void handleInOutUse(const DIMemoryUse &Use);
|
||||
void handleEscapeUse(const DIMemoryUse &Use);
|
||||
|
||||
@@ -542,8 +543,21 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
|
||||
// Keep track of all the uses that aren't loads or escapes. These are
|
||||
// important uses that we'll visit, but we don't consider them definition
|
||||
// points for liveness computation purposes.
|
||||
if (Use.Kind == DIUseKind::Load || Use.Kind == DIUseKind::Escape)
|
||||
switch (Use.Kind) {
|
||||
case DIUseKind::Load:
|
||||
case DIUseKind::LoadForTypeOfSelf:
|
||||
case DIUseKind::Escape:
|
||||
continue;
|
||||
case DIUseKind::Assign:
|
||||
case DIUseKind::IndirectIn:
|
||||
case DIUseKind::InitOrAssign:
|
||||
case DIUseKind::InOutArgument:
|
||||
case DIUseKind::Initialization:
|
||||
case DIUseKind::InOutSelfArgument:
|
||||
case DIUseKind::PartialStore:
|
||||
case DIUseKind::SelfInit:
|
||||
break;
|
||||
}
|
||||
|
||||
NonLoadUses[Use.Inst] = ui;
|
||||
|
||||
@@ -790,6 +804,8 @@ void LifetimeChecker::doIt() {
|
||||
case DIUseKind::SelfInit:
|
||||
handleSelfInitUse(Use);
|
||||
break;
|
||||
case DIUseKind::LoadForTypeOfSelf:
|
||||
handleLoadForTypeOfSelfUse(Use);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,6 +842,28 @@ void LifetimeChecker::handleLoadUse(unsigned UseID) {
|
||||
return handleLoadUseFailure(Use, IsSuperInitComplete, FailedSelfUse);
|
||||
}
|
||||
|
||||
void LifetimeChecker::handleLoadForTypeOfSelfUse(const DIMemoryUse &Use) {
|
||||
bool IsSuperInitComplete, FailedSelfUse;
|
||||
// If the value is not definitively initialized, replace the
|
||||
// value_metatype instruction with the metatype argument that was passed into
|
||||
// the initializer.
|
||||
if (!isInitializedAtUse(Use, &IsSuperInitComplete, &FailedSelfUse)) {
|
||||
auto load = cast<SingleValueInstruction>(Use.Inst);
|
||||
|
||||
ValueMetatypeInst *valueMetatype = nullptr;
|
||||
for (auto use : load->getUses()) {
|
||||
valueMetatype = dyn_cast<ValueMetatypeInst>(use->getUser());
|
||||
if (valueMetatype)
|
||||
break;
|
||||
}
|
||||
assert(valueMetatype);
|
||||
auto metatypeArgument = load->getFunction()->getEntryBlock()->getArguments()
|
||||
.back();
|
||||
replaceAllSimplifiedUsesAndErase(valueMetatype, metatypeArgument,
|
||||
[](SILInstruction*) { });
|
||||
}
|
||||
}
|
||||
|
||||
void LifetimeChecker::emitSelfConsumedDiagnostic(SILInstruction *Inst) {
|
||||
if (!shouldEmitError(Inst))
|
||||
return;
|
||||
@@ -1930,12 +1968,13 @@ void LifetimeChecker::processUninitializedRelease(SILInstruction *Release,
|
||||
auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
|
||||
SILValue Metatype;
|
||||
|
||||
// In an inherited convenience initializer, we must use the dynamic
|
||||
// type of the object since nothing is initialized yet.
|
||||
if (TheMemory.isDelegatingInit())
|
||||
Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
|
||||
else
|
||||
Metatype = B.createMetatype(Loc, SILMetatypeTy);
|
||||
// A convenience initializer should never deal in partially allocated
|
||||
// objects.
|
||||
assert(!TheMemory.isDelegatingInit());
|
||||
|
||||
// In a designated initializer, we know the class of the thing
|
||||
// we're cleaning up statically.
|
||||
Metatype = B.createMetatype(Loc, SILMetatypeTy);
|
||||
|
||||
// We've already destroyed any instance variables initialized by this
|
||||
// constructor, now destroy instance variables initialized by subclass
|
||||
|
||||
@@ -201,7 +201,6 @@ static bool areOverrideCompatibleSimple(ValueDecl *decl,
|
||||
// Factory initializers cannot be overridden.
|
||||
if (parentCtor->isFactoryInit())
|
||||
return false;
|
||||
|
||||
} else if (auto var = dyn_cast<VarDecl>(decl)) {
|
||||
auto parentVar = cast<VarDecl>(parentDecl);
|
||||
if (var->isStatic() != parentVar->isStatic())
|
||||
@@ -1309,10 +1308,9 @@ OverrideRequiresKeyword swift::overrideRequiresKeyword(ValueDecl *overridden) {
|
||||
}
|
||||
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(overridden)) {
|
||||
if (ctor->isDesignatedInit() && !ctor->isRequired())
|
||||
return OverrideRequiresKeyword::Always;
|
||||
|
||||
return OverrideRequiresKeyword::Never;
|
||||
return !ctor->isDesignatedInit() || ctor->isRequired()
|
||||
? OverrideRequiresKeyword::Never
|
||||
: OverrideRequiresKeyword::Always;
|
||||
}
|
||||
|
||||
return OverrideRequiresKeyword::Always;
|
||||
|
||||
@@ -2785,11 +2785,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID) {
|
||||
errorFlags |= DeclDeserializationError::NeedsVTableEntry;
|
||||
DeclAttributes attrs;
|
||||
attrs.setRawAttributeChain(DAttrs);
|
||||
if (attrs.hasAttribute<RequiredAttr>())
|
||||
errorFlags |= DeclDeserializationError::NeedsAllocatingVTableEntry;
|
||||
}
|
||||
if (firstTimeRequired)
|
||||
errorFlags |= DeclDeserializationError::NeedsAllocatingVTableEntry;
|
||||
|
||||
auto overridden = getDeclChecked(overriddenID);
|
||||
if (!overridden) {
|
||||
@@ -4943,13 +4939,12 @@ Decl *handleErrorAndSupplyMissingClassMember(ASTContext &context,
|
||||
auto handleMissingClassMember = [&](const DeclDeserializationError &error) {
|
||||
if (error.isDesignatedInitializer())
|
||||
containingClass->setHasMissingDesignatedInitializers();
|
||||
if (error.needsVTableEntry() || error.needsAllocatingVTableEntry())
|
||||
if (error.needsVTableEntry())
|
||||
containingClass->setHasMissingVTableEntries();
|
||||
|
||||
if (error.getName().getBaseName() == DeclBaseName::createConstructor()) {
|
||||
suppliedMissingMember = MissingMemberDecl::forInitializer(
|
||||
context, containingClass, error.getName(), error.needsVTableEntry(),
|
||||
error.needsAllocatingVTableEntry());
|
||||
context, containingClass, error.getName(), error.needsVTableEntry());
|
||||
} else if (error.needsVTableEntry()) {
|
||||
suppliedMissingMember = MissingMemberDecl::forMethod(
|
||||
context, containingClass, error.getName(), error.needsVTableEntry());
|
||||
@@ -4971,14 +4966,13 @@ Decl *handleErrorAndSupplyMissingProtoMember(ASTContext &context,
|
||||
|
||||
auto handleMissingProtocolMember =
|
||||
[&](const DeclDeserializationError &error) {
|
||||
assert(!error.needsAllocatingVTableEntry());
|
||||
if (error.needsVTableEntry())
|
||||
containingProto->setHasMissingRequirements(true);
|
||||
|
||||
if (error.getName().getBaseName() == DeclBaseName::createConstructor()) {
|
||||
suppliedMissingMember = MissingMemberDecl::forInitializer(
|
||||
context, containingProto, error.getName(),
|
||||
error.needsVTableEntry(), error.needsAllocatingVTableEntry());
|
||||
error.needsVTableEntry());
|
||||
return;
|
||||
}
|
||||
if (error.needsVTableEntry()) {
|
||||
|
||||
@@ -227,8 +227,7 @@ public:
|
||||
enum Flag : unsigned {
|
||||
DesignatedInitializer = 1 << 0,
|
||||
NeedsVTableEntry = 1 << 1,
|
||||
NeedsAllocatingVTableEntry = 1 << 2,
|
||||
NeedsFieldOffsetVectorEntry = 1 << 3,
|
||||
NeedsFieldOffsetVectorEntry = 1 << 2,
|
||||
};
|
||||
using Flags = OptionSet<Flag>;
|
||||
|
||||
@@ -247,9 +246,6 @@ public:
|
||||
bool needsVTableEntry() const {
|
||||
return flags.contains(Flag::NeedsVTableEntry);
|
||||
}
|
||||
bool needsAllocatingVTableEntry() const {
|
||||
return flags.contains(Flag::NeedsAllocatingVTableEntry);
|
||||
}
|
||||
bool needsFieldOffsetVectorEntry() const {
|
||||
return flags.contains(Flag::NeedsFieldOffsetVectorEntry);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ class A {}
|
||||
// V-table entry #1: flags.
|
||||
// CHECK-SAME: i32 1
|
||||
// V-table entry #1: invocation function.
|
||||
// CHECK-SAME: @"$S14class_metadata1ACACycfc"
|
||||
// CHECK-SAME: } }>, section
|
||||
// CHECK-SAME: @"$S14class_metadata1ACACycfC"
|
||||
// CHECK-SAME: }>, section
|
||||
|
||||
class B : A {}
|
||||
|
||||
@@ -72,7 +72,7 @@ class B : A {}
|
||||
// Override table entry #1: base method.
|
||||
// CHECK-SAME: @"$S14class_metadata1ACMn", i32 0, i32 13
|
||||
// Override table entry #1: invocation function.
|
||||
// CHECK-SAME: @"$S14class_metadata1BCACycfc"
|
||||
// CHECK-SAME: @"$S14class_metadata1BCACycfC"
|
||||
|
||||
// CHECK-SAME: }>, section
|
||||
|
||||
@@ -128,7 +128,7 @@ class C<T> : B {}
|
||||
// Override table entry #1: base method.
|
||||
// CHECK-SAME: @"$S14class_metadata1ACMn", i32 0, i32 13
|
||||
// Override table entry #1: invocation function.
|
||||
// CHECK-SAME: @"$S14class_metadata1CCACyxGycfc"
|
||||
// CHECK-SAME: @"$S14class_metadata1CCACyxGycfC"
|
||||
// CHECK-SAME: }>, section
|
||||
|
||||
// CHECK-LABEL: @"$S14class_metadata1CCMP" =
|
||||
@@ -169,8 +169,8 @@ class D : E {}
|
||||
// Override table entry #1: base class.
|
||||
// CHECK-SAME: @"got.$S14class_metadata1ECMn.1"
|
||||
// Override table entry #1: base method.
|
||||
// CHECK-SAME: @"got.$S14class_metadata1ECACycfcTq"
|
||||
// CHECK-SAME: @"got.$S14class_metadata1ECACycfCTq"
|
||||
// Override table entry #1: invocation function.
|
||||
// CHECK-SAME: @"$S14class_metadata1DCACycfc"
|
||||
// CHECK-SAME: @"$S14class_metadata1DCACycfC"
|
||||
// CHECK-SAME: }>, section
|
||||
class E {}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
// CHECK: @"$S16class_resilience14ResilientChildC5fields5Int32VvpWvd" = hidden global [[INT]] {{8|16}}
|
||||
|
||||
// CHECK: @"$S15resilient_class22ResilientOutsideParentCACycfcTq" = external global %swift.method_descriptor
|
||||
|
||||
// CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}{{(dllexport )?}}global [[BOUNDS:{ (i32|i64), i32, i32 }]] zeroinitializer
|
||||
|
||||
// CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}{{(dllexport )?}}constant [[BOUNDS]]
|
||||
@@ -77,9 +75,9 @@
|
||||
// -- base class:
|
||||
// CHECK-SAME: @"got.$S15resilient_class22ResilientOutsideParentCMn"
|
||||
// -- base method:
|
||||
// CHECK-SAME: @"got.$S15resilient_class22ResilientOutsideParentCACycfcTq"
|
||||
// CHECK-SAME: @"got.$S15resilient_class22ResilientOutsideParentCACycfCTq"
|
||||
// -- implementation:
|
||||
// CHECK-SAME: @"$S16class_resilience14ResilientChildCACycfc"
|
||||
// CHECK-SAME: @"$S16class_resilience14ResilientChildCACycfC"
|
||||
// CHECK-SAME: }
|
||||
// CHECK-SAME: }>
|
||||
|
||||
@@ -129,9 +127,9 @@
|
||||
// CHECK: @"$S16class_resilience21ResilientGenericChildC5fields5Int32VvsTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience21ResilientGenericChildC5fields5Int32VvMTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
|
||||
// CHECK: @"$S16class_resilience17MyResilientParentCACycfcTq" = hidden alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience24MyResilientGenericParentC1tACyxGx_tcfcTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience24MyResilientConcreteChildC1xACSi_tcfcTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience17MyResilientParentCACycfCTq" = hidden alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience24MyResilientGenericParentC1tACyxGx_tcfCTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
// CHECK: @"$S16class_resilience24MyResilientConcreteChildC1xACSi_tcfCTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
|
||||
|
||||
import resilient_class
|
||||
import resilient_struct
|
||||
@@ -347,23 +345,6 @@ extension ResilientGenericOutsideParent {
|
||||
// CHECK-NEXT: call void @swift_endAccess
|
||||
// CHECK: ret i32 [[FIELD_VALUE]]
|
||||
|
||||
|
||||
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %T16class_resilience14ResilientChildC* @"$S16class_resilience14ResilientChildCACycfc"(%T16class_resilience14ResilientChildC* swiftself)
|
||||
// CHECK: [[SUPER_SELF:%.*]] = bitcast %T16class_resilience14ResilientChildC* %0 to %T15resilient_class22ResilientOutsideParentC*
|
||||
|
||||
// Note: we know the superclass of ResilientChild statically, so we can emit
|
||||
// it directly.
|
||||
|
||||
// CHECK: [[SUPER_METADATA_RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S15resilient_class22ResilientOutsideParentCMa"
|
||||
// CHECK-NEXT: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[SUPER_METADATA_RESPONSE]], 0
|
||||
|
||||
// CHECK: [[SUPER_METHOD:%.*]] = call swiftcc i8* @"$S15resilient_class22ResilientOutsideParentCMu"(%swift.type* [[SUPER_METADATA:%.*]], %swift.method_descriptor* @"$S15resilient_class22ResilientOutsideParentCACycfcTq")
|
||||
// CHECK-NEXT: [[SUPER_METHOD_FN:%.*]] = bitcast i8* [[SUPER_METHOD]] to %T15resilient_class22ResilientOutsideParentC* (%T15resilient_class22ResilientOutsideParentC*)*
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = call swiftcc %T15resilient_class22ResilientOutsideParentC* [[SUPER_METHOD_FN]](%T15resilient_class22ResilientOutsideParentC* swiftself [[SUPER_SELF]])
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = bitcast %T15resilient_class22ResilientOutsideParentC* [[RESULT]] to %T16class_resilience14ResilientChildC*
|
||||
// CHECK: ret %T16class_resilience14ResilientChildC* [[NEW_SELF]]
|
||||
|
||||
|
||||
// ResilientGenericChild.field getter
|
||||
|
||||
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @"$S16class_resilience21ResilientGenericChildC5fields5Int32Vvg"(%T16class_resilience21ResilientGenericChildC* swiftself)
|
||||
|
||||
@@ -8,10 +8,10 @@ import Foundation
|
||||
|
||||
// CHECK: @"$S28class_with_stub_initializers3FooCN" =
|
||||
// -- The init() stub should get no vtable entry
|
||||
// CHECK-NOT: %T28class_with_stub_initializers3FooC* (%T28class_with_stub_initializers3FooC*)*
|
||||
// CHECK: %T28class_with_stub_initializers3FooC* (i64, %T28class_with_stub_initializers3FooC*)*
|
||||
// CHECK-NOT: %T28class_with_stub_initializers3FooC* (%swift.type*)*
|
||||
// CHECK: %T28class_with_stub_initializers3FooC* (i64, %swift.type*)*
|
||||
// -- The init() stub should get no vtable entry
|
||||
// CHECK-NOT: %T28class_with_stub_initializers3FooC* (%T28class_with_stub_initializers3FooC*)*
|
||||
// CHECK-NOT: %T28class_with_stub_initializers3FooC* (%swift.type*)*
|
||||
// CHECK: {{^(@|define)}}
|
||||
class Foo: NSObject {
|
||||
init(x: Int64) { super.init() }
|
||||
|
||||
@@ -20,7 +20,7 @@ public class Class {
|
||||
// -- vtable
|
||||
// CHECK-SAME: %swift.method_descriptor {
|
||||
// CHECK-SAME: i32 1,
|
||||
// CHECK-SAME: @"$S11dead_method5ClassCACycfc"
|
||||
// CHECK-SAME: @"$S11dead_method5ClassCACycfC"
|
||||
// CHECK-SAME: }
|
||||
|
||||
// CHECK-SAME: %swift.method_descriptor {
|
||||
@@ -46,7 +46,7 @@ public class Class {
|
||||
// CHECK-SAME: i8* null,
|
||||
|
||||
// -- vtable
|
||||
// CHECK-SAME: %T11dead_method5ClassC* (%T11dead_method5ClassC*)* @"$S11dead_method5ClassCACycfc",
|
||||
// CHECK-SAME: %T11dead_method5ClassC* (%swift.type*)* @"$S11dead_method5ClassCACycfC",
|
||||
// CHECK-SAME: void (%T11dead_method5ClassC*)* @"$S11dead_method5ClassC4liveyyF",
|
||||
// CHECK-SAME: i8* bitcast (void ()* @swift_deletedMethodError to i8*)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class Concrete : Derived<Int> {
|
||||
// -- vtable entry for 'm2()'
|
||||
// CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$S14generic_vtable4BaseC2m2yyF"
|
||||
// -- vtable entry for 'init()'
|
||||
// CHECK-SAME: %T14generic_vtable4BaseC* (%T14generic_vtable4BaseC*)* @"$S14generic_vtable4BaseCACycfc"
|
||||
// CHECK-SAME: %T14generic_vtable4BaseC* (%swift.type*)* @"$S14generic_vtable4BaseCACycfC"
|
||||
// --
|
||||
// CHECK-SAME: , align
|
||||
|
||||
@@ -69,7 +69,7 @@ public class Concrete : Derived<Int> {
|
||||
// -- override for constructor
|
||||
// CHECK-SAME: @"$S14generic_vtable4BaseCMn"
|
||||
// CHECK-SAME: @"$S14generic_vtable4BaseCMn", i32 0, i32 15
|
||||
// CHECK-SAME: @"$S14generic_vtable7DerivedCACyxGycfc"
|
||||
// CHECK-SAME: @"$S14generic_vtable7DerivedCACyxGycfC"
|
||||
// CHECK-SAME: section "{{.*}}", align 4
|
||||
|
||||
//// Type metadata pattern for 'Derived' has an empty vtable, filled in at
|
||||
@@ -103,7 +103,7 @@ public class Concrete : Derived<Int> {
|
||||
// -- override for constructor
|
||||
// CHECK-SAME: @"$S14generic_vtable4BaseCMn"
|
||||
// CHECK-SAME: @"$S14generic_vtable4BaseCMn", i32 0, i32 15
|
||||
// CHECK-SAME: @"$S14generic_vtable8ConcreteCACycfc"
|
||||
// CHECK-SAME: @"$S14generic_vtable8ConcreteCACycfC"
|
||||
// --
|
||||
// CHECK-SAME: section "{{.*}}", align 4
|
||||
|
||||
@@ -117,7 +117,7 @@ public class Concrete : Derived<Int> {
|
||||
// -- vtable entry for 'm2()'
|
||||
// CHECK-SAME: void (%T14generic_vtable7DerivedC*)* @"$S14generic_vtable7DerivedC2m2yyF"
|
||||
// -- vtable entry for 'init()'
|
||||
// CHECK-SAME: %T14generic_vtable8ConcreteC* (%T14generic_vtable8ConcreteC*)* @"$S14generic_vtable8ConcreteCACycfc"
|
||||
// CHECK-SAME: %T14generic_vtable8ConcreteC* (%swift.type*)* @"$S14generic_vtable8ConcreteCACycfC"
|
||||
// -- vtable entry for 'm3()'
|
||||
// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* @"$S14generic_vtable8ConcreteC2m3yyF"
|
||||
// -- vtable entry for 'm4()'
|
||||
@@ -130,7 +130,7 @@ public class Concrete : Derived<Int> {
|
||||
|
||||
// CHECK-LABEL: @"$S14generic_vtable4BaseC2m1yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}>* @"$S14generic_vtable4BaseCMn", i32 0, i32 13)
|
||||
// CHECK-LABEL: @"$S14generic_vtable4BaseC2m2yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 14)
|
||||
// CHECK-LABEL: @"$S14generic_vtable4BaseCACycfcTq" = hidden alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 15)
|
||||
// CHECK-LABEL: @"$S14generic_vtable4BaseCACycfCTq" = hidden alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 15)
|
||||
|
||||
// CHECK-LABEL: @"$S14generic_vtable7DerivedC2m3yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}>* @"$S14generic_vtable7DerivedCMn", i32 0, i32 23)
|
||||
|
||||
|
||||
@@ -6,37 +6,36 @@
|
||||
// CHECK: [[OPAQUE:%swift.opaque]] = type opaque
|
||||
// CHECK: [[TYPE:%swift.type]] = type
|
||||
|
||||
// CHECK: @"$S14ivar_destroyer17NonTrivialDerivedCMf" = internal global <{ {{.*}} }> <{
|
||||
// \ CHECK: i8* null,
|
||||
// \ CHECK: i8** @"$SBoWV",
|
||||
// \ CHECK: i64 ptrtoint ([[OBJCCLASS]]* @"$S14ivar_destroyer17NonTrivialDerivedCMm" to i64),
|
||||
// \ CHECK: [[TYPE]]* bitcast (i64* getelementptr inbounds (<{ {{.*}} }>, <{ {{.*}} }>* @"$S14ivar_destroyer11TrivialBaseCMf", i32 0, i32 2) to [[TYPE]]*),
|
||||
// \ CHECK: [[OPAQUE]]* @_objc_empty_cache,
|
||||
// \ CHECK: [[OPAQUE]]* null,
|
||||
// \ CHECK: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 {{1|2}}),
|
||||
// \ CHECK: i32 {{3|2}},
|
||||
// \ CHECK: i32 0,
|
||||
// \ CHECK: i32 24,
|
||||
// \ CHECK: i16 7,
|
||||
// \ CHECK: i16 0,
|
||||
// \ CHECK: i32 120,
|
||||
// \ CHECK: i32 16,
|
||||
// \ CHECK: <{ {{.*}} }>* @"$S14ivar_destroyer17NonTrivialDerivedCMn"
|
||||
// \ CHECK: void (%T14ivar_destroyer17NonTrivialDerivedC*)* @"$S14ivar_destroyer17NonTrivialDerivedCfE",
|
||||
// \ CHECK: i8* bitcast (void ()* @swift_deletedMethodError to i8*),
|
||||
// \ CHECK: %T14ivar_destroyer17NonTrivialDerivedC* ([[TYPE]]*)* @alloc_NonTrivialDerived,
|
||||
// \ CHECK: i64 16
|
||||
// \ CHECK: }>
|
||||
// CHECK-LABEL: @"$S14ivar_destroyer17NonTrivialDerivedCMf" = internal global <{ {{.*}} }> <{
|
||||
// CHECK-SAME: i8* null,
|
||||
// CHECK-SAME: i8** @"$SBoWV",
|
||||
// CHECK-SAME: i64 ptrtoint ([[OBJCCLASS]]* @"$S14ivar_destroyer17NonTrivialDerivedCMm" to i64),
|
||||
// CHECK-SAME: [[TYPE]]* bitcast (i64* getelementptr inbounds (<{ {{.*}} }>, <{ {{.*}} }>* @"$S14ivar_destroyer11TrivialBaseCMf", i32 0, i32 2) to [[TYPE]]*),
|
||||
// CHECK-SAME: [[OPAQUE]]* @_objc_empty_cache,
|
||||
// CHECK-SAME: [[OPAQUE]]* null,
|
||||
// CHECK-SAME: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 {{1|2}}),
|
||||
// CHECK-SAME: i32 {{3|2}},
|
||||
// CHECK-SAME: i32 0,
|
||||
// CHECK-SAME: i32 24,
|
||||
// CHECK-SAME: i16 7,
|
||||
// CHECK-SAME: i16 0,
|
||||
// CHECK-SAME: i32 112,
|
||||
// CHECK-SAME: i32 16,
|
||||
// CHECK-SAME: <{ {{.*}} }>* @"$S14ivar_destroyer17NonTrivialDerivedCMn"
|
||||
// CHECK-SAME: void (%T14ivar_destroyer17NonTrivialDerivedC*)* @"$S14ivar_destroyer17NonTrivialDerivedCfE",
|
||||
// CHECK-SAME: %T14ivar_destroyer17NonTrivialDerivedC* ([[TYPE]]*)* @alloc_NonTrivialDerived
|
||||
// CHECK-SAME: i64 16
|
||||
// CHECK-SAME: }>
|
||||
|
||||
class Pachyderm {}
|
||||
sil_vtable Pachyderm {}
|
||||
|
||||
class TrivialBase {}
|
||||
|
||||
sil public_external @init_TrivialBase : $@convention(method) (@owned TrivialBase) -> @owned TrivialBase
|
||||
sil public_external @alloc_TrivialBase : $@convention(method) (@thick TrivialBase.Type) -> @owned TrivialBase
|
||||
|
||||
sil_vtable TrivialBase {
|
||||
#TrivialBase.init!initializer.1: @init_TrivialBase
|
||||
#TrivialBase.init!allocator.1: @alloc_TrivialBase
|
||||
}
|
||||
|
||||
class NonTrivialDerived : TrivialBase {
|
||||
@@ -45,12 +44,10 @@ class NonTrivialDerived : TrivialBase {
|
||||
required override init()
|
||||
}
|
||||
|
||||
sil public_external @init_NonTrivialDerived : $@convention(method) (@owned NonTrivialDerived) -> @owned NonTrivialDerived
|
||||
sil public_external @alloc_NonTrivialDerived : $@convention(method) (@thick NonTrivialDerived.Type) -> @owned NonTrivialDerived
|
||||
sil public_external @$S14ivar_destroyer17NonTrivialDerivedCfE : $@convention(method) (@guaranteed NonTrivialDerived) -> ()
|
||||
|
||||
sil_vtable NonTrivialDerived {
|
||||
#NonTrivialDerived.init!initializer.1: @init_NonTrivialDerived [override]
|
||||
#NonTrivialDerived.init!allocator.1: @alloc_NonTrivialDerived
|
||||
#TrivialBase.init!allocator.1: @alloc_NonTrivialDerived [override]
|
||||
#NonTrivialDerived!ivardestroyer.1: @$S14ivar_destroyer17NonTrivialDerivedCfE
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
// Method descriptors linkage:
|
||||
|
||||
// - internal initializer descriptor has hidden linkage when class is public:
|
||||
// CHECK-LABEL: @"$S14method_linkage11PublicClassCACycfcTq" = hidden alias
|
||||
// CHECK-LABEL: @"$S14method_linkage11PublicClassCACycfCTq" = hidden alias
|
||||
|
||||
// - internal initializer descriptor has public linkage when class is open:
|
||||
// CHECK-LABEL: @"$S14method_linkage9OpenClassCACycfcTq" ={{( dllexport)?}}{{( protected)?}} alias
|
||||
// CHECK-LABEL: @"$S14method_linkage9OpenClassCACycfCTq" ={{( dllexport)?}}{{( protected)?}} alias
|
||||
|
||||
// - private method descriptor has internal linkage even though class is open:
|
||||
// CHECK: @"$S14method_linkage9OpenClassC4pfoo0{{.*}}FTq" = internal alias
|
||||
|
||||
@@ -15,7 +15,6 @@ class C {
|
||||
// CHECK: [[C:%T6vtable1CC]] = type <{ %swift.refcounted }>
|
||||
|
||||
sil @$S6vtable1CCACycACmcfC : $@convention(method) (@thick C.Type) -> @owned C
|
||||
sil @$S6vtable1CCACycACmcfc : $@convention(method) (@owned C) -> @owned C
|
||||
sil @$S6vtable1CCfd : $@convention(method) (@owned C) -> @owned Builtin.NativeObject
|
||||
sil @$S6vtable1CCfD : $@convention(method) (@owned C) -> ()
|
||||
|
||||
@@ -28,10 +27,9 @@ sil @$S6vtable1CCfD : $@convention(method) (@owned C) -> ()
|
||||
// CHECK-objc: %swift.opaque* null,
|
||||
// CHECK-objc: i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_DATA__TtC6vtable1C to i64), i64 {{1|2}}),
|
||||
// CHECK-objc: i32 {{3|2}}, i32 0, i32 16, i16 7, i16 0,
|
||||
// CHECK-objc: i32 112, i32 16,
|
||||
// CHECK-objc: i32 104, i32 16,
|
||||
// CHECK-objc: @"$S6vtable1CCMn"
|
||||
// CHECK-objc: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC",
|
||||
// CHECK-objc: [[C]]* ([[C]]*)* @"$S6vtable1CCACycACmcfc"
|
||||
// CHECK-objc: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC"
|
||||
// CHECK-objc: }>
|
||||
|
||||
// CHECK-native: @"$S6vtable1CCMf" = internal global [[C_METADATA_T:<{.*\* }>]] <{
|
||||
@@ -43,13 +41,11 @@ sil @$S6vtable1CCfD : $@convention(method) (@owned C) -> ()
|
||||
// CHECK-native: %swift.opaque* null,
|
||||
// CHECK-native: i64 1,
|
||||
// CHECK-native: i32 {{3|2}}, i32 0, i32 16, i16 7, i16 0,
|
||||
// CHECK-native: i32 112, i32 16,
|
||||
// CHECK-native: i32 104, i32 16,
|
||||
// CHECK-native: @"$S6vtable1CCMn"
|
||||
// CHECK-native: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC",
|
||||
// CHECK-native: [[C]]* ([[C]]*)* @"$S6vtable1CCACycACmcfc"
|
||||
// CHECK-native: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC"
|
||||
// CHECK-native: }>
|
||||
|
||||
sil_vtable C {
|
||||
#C.init!allocator.1: @$S6vtable1CCACycACmcfC
|
||||
#C.init!initializer.1: @$S6vtable1CCACycACmcfc
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public func testBase(b: Base) -> Int32 {
|
||||
// CHECK-NEXT: #Base.foo!1: (Base) -> () -> Int32 : @$S10SILDeclRef4BaseC3foos5Int32VyF // Base.foo()
|
||||
// CHECK-NEXT: #Base.foo!1: (Base) -> (Int32) -> () : @$S10SILDeclRef4BaseC3foo1nys5Int32V_tF // Base.foo(n:)
|
||||
// CHECK-NEXT: #Base.foo!1: (Base) -> (Float) -> Int32 : @$S10SILDeclRef4BaseC3foo1fs5Int32VSf_tF // Base.foo(f:)
|
||||
// CHECK-NEXT: #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10SILDeclRef4BaseCACycfc // Base.init()
|
||||
// CHECK-NEXT: #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10SILDeclRef4BaseCACycfC
|
||||
// CHECK-NEXT: #Base.deinit!deallocator.1: @$S10SILDeclRef4BaseCfD // Base.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class Sub : Base {
|
||||
// CHECK-NEXT: #Base.prop!getter.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivg [override] // accessibility_vtables.Sub.prop.getter : Swift.Int
|
||||
// CHECK-NEXT: #Base.prop!setter.1: {{.*}} : @$S28accessibility_vtables_helper4BaseC4propSivs [inherited] // accessibility_vtables_helper.Base.prop.setter : Swift.Int
|
||||
// CHECK-NEXT: #Base.prop!modify.1: {{.*}} : @$S28accessibility_vtables_helper4BaseC4propSivM [inherited] // accessibility_vtables_helper.Base.prop.modify : Swift.Int
|
||||
// CHECK-NEXT: #Base.init!initializer.1: {{.*}} : @$S21accessibility_vtables3SubCACycfc [override] // accessibility_vtables.Sub.init() -> accessibility_vtables.Sub
|
||||
// CHECK-NEXT: #Base.init!allocator.1: {{.*}} : @$S21accessibility_vtables3SubCACycfC [override]
|
||||
// CHECK-NEXT: #Sub.internalMethod!1: {{.*}} : @$S21accessibility_vtables3SubC14internalMethodyyF
|
||||
// CHECK-NEXT: #Sub.prop!setter.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivs // accessibility_vtables.Sub.prop.setter : Swift.Int
|
||||
// CHECK-NEXT: #Sub.prop!modify.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivM // accessibility_vtables.Sub.prop.modify : Swift.Int
|
||||
@@ -41,7 +41,7 @@ class InternalSub : InternalBase {
|
||||
// CHECK-NEXT: #InternalBase.prop!getter.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivg [override] // accessibility_vtables.InternalSub.prop.getter : Swift.Int
|
||||
// CHECK-NEXT: #InternalBase.prop!setter.1: {{.*}} : @$S21accessibility_vtables12InternalBaseC4propSivs [inherited] // accessibility_vtables.InternalBase.prop.setter : Swift.Int
|
||||
// CHECK-NEXT: #InternalBase.prop!modify.1: {{.*}} : @$S21accessibility_vtables12InternalBaseC4propSivM [inherited] // accessibility_vtables.InternalBase.prop.modify : Swift.Int
|
||||
// CHECK-NEXT: #InternalBase.init!initializer.1: {{.*}} : @$S21accessibility_vtables11InternalSubCACycfc [override]
|
||||
// CHECK-NEXT: #InternalBase.init!allocator.1: {{.*}} : @$S21accessibility_vtables11InternalSubCACycfC [override]
|
||||
// CHECK-NEXT: #InternalSub.method!1: {{.*}} : @$S21accessibility_vtables11InternalSubC6methodyyF
|
||||
// CHECK-NEXT: #InternalSub.prop!setter.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivs // accessibility_vtables.InternalSub.prop.setter : Swift.Int
|
||||
// CHECK-NEXT: #InternalSub.prop!modify.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivM // accessibility_vtables.InternalSub.prop.modify : Swift.Int
|
||||
|
||||
@@ -419,7 +419,7 @@ class Sub : Base {
|
||||
// CHECK-NEXT: #Base.value!getter.1: (Base) -> () -> Int32 : @$S10addressors4BaseC5values5Int32Vvg
|
||||
// CHECK-NEXT: #Base.value!setter.1: (Base) -> (Int32) -> () : @$S10addressors4BaseC5values5Int32Vvs
|
||||
// CHECK-NEXT: #Base.value!modify.1: (Base) -> () -> () : @$S10addressors4BaseC5values5Int32VvM
|
||||
// CHECK-NEXT: #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10addressors4BaseCACycfc
|
||||
// CHECK-NEXT: #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10addressors4BaseCACycfC
|
||||
// CHECK-NEXT: #Base.deinit!deallocator.1: @$S10addressors4BaseCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -430,6 +430,6 @@ class Sub : Base {
|
||||
// CHECK-NEXT: #Base.value!getter.1: (Base) -> () -> Int32 : @$S10addressors3SubC5values5Int32Vvg
|
||||
// CHECK-NEXT: #Base.value!setter.1: (Base) -> (Int32) -> () : @$S10addressors3SubC5values5Int32Vvs
|
||||
// CHECK-NEXT: #Base.value!modify.1: (Base) -> () -> () : @$S10addressors3SubC5values5Int32VvM
|
||||
// CHECK-NEXT: #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10addressors3SubCACycfc
|
||||
// CHECK-NEXT: #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10addressors3SubCACycfC
|
||||
// CHECK-NEXT: #Sub.deinit!deallocator.1: @$S10addressors3SubCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -41,7 +41,7 @@ class SubclassOfOutsideChild : ResilientOutsideChild {
|
||||
// Note: no entries for [inherited] methods
|
||||
|
||||
// CHECK-LABEL: sil_vtable SubclassOfOutsideChild {
|
||||
// CHECK-NEXT: #ResilientOutsideParent.init!initializer.1: (ResilientOutsideParent.Type) -> () -> ResilientOutsideParent : @$S16class_resilience22SubclassOfOutsideChildCACycfc [override]
|
||||
// CHECK-NEXT: #ResilientOutsideParent.init!allocator.1: (ResilientOutsideParent.Type) -> () -> ResilientOutsideParent : @$S16class_resilience22SubclassOfOutsideChildCACycfC [override]
|
||||
// CHECK-NEXT: #ResilientOutsideParent.method!1: (ResilientOutsideParent) -> () -> () : @$S16class_resilience22SubclassOfOutsideChildC6methodyyF [override]
|
||||
// CHECK-NEXT: #SubclassOfOutsideChild.newMethod!1: (SubclassOfOutsideChild) -> () -> () : @$S16class_resilience22SubclassOfOutsideChildC9newMethodyyF
|
||||
// CHECK-NEXT: #SubclassOfOutsideChild.deinit!deallocator.1: @$S16class_resilience22SubclassOfOutsideChildCfD
|
||||
|
||||
@@ -5,24 +5,12 @@ struct X { }
|
||||
class A {
|
||||
// CHECK-LABEL: sil hidden @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick A.Type) -> @owned A
|
||||
// CHECK: bb0([[SELF_META:%[0-9]+]] : @trivial $@thick A.Type):
|
||||
// CHECK: [[SELF:%[0-9]+]] = alloc_ref_dynamic [[SELF_META]] : $@thick A.Type, $A
|
||||
// CHECK: [[OTHER_INIT:%[0-9]+]] = function_ref @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned A) -> @owned A
|
||||
// CHECK: [[RESULT:%[0-9]+]] = apply [[OTHER_INIT]]([[SELF]]) : $@convention(method) (@owned A) -> @owned A
|
||||
// CHECK: return [[RESULT]] : $A
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned A) -> @owned A
|
||||
// CHECK: bb0([[SELF_PARAM:%[0-9]+]] : @owned $A):
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var A }
|
||||
// CHECK: [[UNINIT_SELF:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]] : ${ var A }
|
||||
// CHECK: [[PB:%.*]] = project_box [[UNINIT_SELF]]
|
||||
// CHECK: store [[SELF_PARAM]] to [init] [[PB]] : $*A
|
||||
// CHECK: [[SELFP:%[0-9]+]] = load [take] [[PB]] : $*A
|
||||
// CHECK: [[X_META:%[0-9]+]] = metatype $@thin X.Type
|
||||
// CHECK: [[X_INIT:%[0-9]+]] = function_ref @$S20complete_object_init1XV{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thin X.Type) -> X
|
||||
// CHECK: [[X:%[0-9]+]] = apply [[X_INIT]]([[X_META]]) : $@convention(method) (@thin X.Type) -> X
|
||||
// CHECK: [[INIT:%[0-9]+]] = class_method [[SELFP]] : $A, #A.init!initializer.1 : (A.Type) -> (X) -> A, $@convention(method) (X, @owned A) -> @owned A
|
||||
// CHECK: [[INIT_RESULT:%[0-9]+]] = apply [[INIT]]([[X]], [[SELFP]]) : $@convention(method) (X, @owned A) -> @owned A
|
||||
// CHECK: store [[INIT_RESULT]] to [init] [[PB]] : $*A
|
||||
// CHECK: [[INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick A.Type, #A.init!allocator.1
|
||||
// CHECK: [[INIT_RESULT:%[0-9]+]] = apply [[INIT]]({{%[^,]*}}, [[SELF_META]])
|
||||
// CHECK: assign [[INIT_RESULT]] to [[PB]] : $*A
|
||||
// CHECK: [[RESULT:%[0-9]+]] = load [copy] [[PB]] : $*A
|
||||
// CHECK: destroy_value [[UNINIT_SELF]] : ${ var A }
|
||||
// CHECK: return [[RESULT]] : $A
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
|
||||
|
||||
class X {
|
||||
init() {
|
||||
}
|
||||
|
||||
// Convenience inits must dynamically dispatch designated inits...
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
|
||||
// CHECK: class_method {{%.*}}, #X.init!allocator.1
|
||||
convenience init(convenience: ()) {
|
||||
self.init()
|
||||
}
|
||||
|
||||
// ...but can statically invoke peer convenience inits
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
|
||||
convenience init(doubleConvenience: ()) {
|
||||
self.init(convenience: ())
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
|
||||
required init(required: ()) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
|
||||
required convenience init(requiredConvenience: ()) {
|
||||
self.init(required: ())
|
||||
}
|
||||
|
||||
// Convenience inits must dynamically dispatch required peer convenience inits
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
|
||||
// CHECK: class_method {{%.*}}, #X.init!allocator.1
|
||||
required convenience init(requiredDoubleConvenience: ()) {
|
||||
self.init(requiredDoubleConvenience: ())
|
||||
}
|
||||
}
|
||||
|
||||
class Y: X {
|
||||
// This is really a designated initializer. Ensure that we don't try to
|
||||
// treat it as an override of the base class convenience initializer (and
|
||||
// override a nonexistent vtable entry) just because it has the same name.
|
||||
init(convenience: ()) {
|
||||
super.init()
|
||||
}
|
||||
|
||||
// Conversely, a designated init *can* be overridden as a convenience
|
||||
// initializer.
|
||||
override convenience init() {
|
||||
self.init(convenience: ())
|
||||
}
|
||||
|
||||
required init(required: ()) { super.init() }
|
||||
required init(requiredConvenience: ()) { super.init() }
|
||||
required init(requiredDoubleConvenience: ()) { super.init() }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation11invocations2xtyAA1XCm_tF
|
||||
func invocations(xt: X.Type) {
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XCACycfC
|
||||
_ = X()
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
|
||||
_ = X(convenience: ())
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
|
||||
_ = X(doubleConvenience: ())
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
|
||||
_ = X(required: ())
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
|
||||
_ = X(requiredConvenience: ())
|
||||
// CHECK: function_ref @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
|
||||
_ = X(requiredDoubleConvenience: ())
|
||||
|
||||
// CHECK: class_method {{%.*}}, #X.init!allocator.1
|
||||
_ = xt.init(required: ())
|
||||
// CHECK: class_method {{%.*}}, #X.init!allocator.1
|
||||
_ = xt.init(requiredConvenience: ())
|
||||
// CHECK: class_method {{%.*}}, #X.init!allocator.1
|
||||
_ = xt.init(requiredDoubleConvenience: ())
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil_vtable X
|
||||
// -- designated init()
|
||||
// CHECK: @$S32convenience_init_peer_delegation1XCACycfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XCACycfc
|
||||
|
||||
// -- no unrequired convenience inits
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfc
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfc
|
||||
|
||||
// -- designated init(required:)
|
||||
// CHECK: @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfc
|
||||
// -- convenience init(requiredConvenience:)
|
||||
// CHECK: @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfc
|
||||
// -- convenience init(requiredDoubleConvenience:)
|
||||
// CHECK: @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfc
|
||||
|
||||
// CHECK-LABEL: sil_vtable Y
|
||||
// -- designated init() overridden by convenience init
|
||||
// CHECK: @$S32convenience_init_peer_delegation1YCACycfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1YCACycfc
|
||||
// -- Y.init(convenience:) is a designated init
|
||||
// CHECK: @$S32convenience_init_peer_delegation1YC0A0ACyt_tcfC
|
||||
// CHECK-NOT: @$S32convenience_init_peer_delegation1YC0A0ACyt_tcfc
|
||||
+10
-10
@@ -328,7 +328,7 @@ func foreignMethodDispatch() {
|
||||
}
|
||||
|
||||
extension Gizmo {
|
||||
// CHECK-LABEL: sil hidden @$SSo5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-LABEL: sil hidden @$SSo5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: objc_method {{%.*}} : $Gizmo, #Gizmo.init!initializer.1.foreign
|
||||
convenience init(convenienceInExtension: Int) {
|
||||
self.init(bellsOn: convenienceInExtension)
|
||||
@@ -499,7 +499,7 @@ public class ConcreteDerived : GenericBase<Int> {
|
||||
|
||||
// Vtable contains entries for native and @objc methods, but not dynamic ones
|
||||
// CHECK-LABEL: sil_vtable Foo {
|
||||
// CHECK-NEXT: #Foo.init!initializer.1: {{.*}} : @$S7dynamic3FooC6nativeACSi_tcfc
|
||||
// CHECK-NEXT: #Foo.init!allocator.1: {{.*}} : @$S7dynamic3FooC6nativeACSi_tcfC
|
||||
// CHECK-NEXT: #Foo.nativeMethod!1: {{.*}} : @$S7dynamic3FooC12nativeMethodyyF
|
||||
// CHECK-NEXT: #Foo.nativeProp!getter.1: {{.*}} : @$S7dynamic3FooC10nativePropSivg // dynamic.Foo.nativeProp.getter : Swift.Int
|
||||
// CHECK-NEXT: #Foo.nativeProp!setter.1: {{.*}} : @$S7dynamic3FooC10nativePropSivs // dynamic.Foo.nativeProp.setter : Swift.Int
|
||||
@@ -507,7 +507,7 @@ public class ConcreteDerived : GenericBase<Int> {
|
||||
// CHECK-NEXT: #Foo.subscript!getter.1: {{.*}} : @$S7dynamic3FooC6nativeS2i_tcig // dynamic.Foo.subscript.getter : (native: Swift.Int) -> Swift.Int
|
||||
// CHECK-NEXT: #Foo.subscript!setter.1: {{.*}} : @$S7dynamic3FooC6nativeS2i_tcis // dynamic.Foo.subscript.setter : (native: Swift.Int) -> Swift.Int
|
||||
// CHECK-NEXT: #Foo.subscript!modify.1:
|
||||
// CHECK-NEXT: #Foo.init!initializer.1: {{.*}} : @$S7dynamic3FooC4objcACSi_tcfc
|
||||
// CHECK-NEXT: #Foo.init!allocator.1: {{.*}} : @$S7dynamic3FooC4objcACSi_tcfC
|
||||
// CHECK-NEXT: #Foo.objcMethod!1: {{.*}} : @$S7dynamic3FooC10objcMethodyyF
|
||||
// CHECK-NEXT: #Foo.objcProp!getter.1: {{.*}} : @$S7dynamic3FooC8objcPropSivg // dynamic.Foo.objcProp.getter : Swift.Int
|
||||
// CHECK-NEXT: #Foo.objcProp!setter.1: {{.*}} : @$S7dynamic3FooC8objcPropSivs // dynamic.Foo.objcProp.setter : Swift.Int
|
||||
@@ -526,20 +526,20 @@ public class ConcreteDerived : GenericBase<Int> {
|
||||
|
||||
// Check vtables for implicitly-inherited initializers
|
||||
// CHECK-LABEL: sil_vtable SubclassWithInheritedInits {
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC6nativeACSi_tcfc
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC4objcACSi_tcfc
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC6nativeACSi_tcfC
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC4objcACSi_tcfC
|
||||
// CHECK-NOT: .init!
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable GrandchildWithInheritedInits {
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC6nativeACSi_tcfc
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC4objcACSi_tcfc
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC6nativeACSi_tcfC
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC4objcACSi_tcfC
|
||||
// CHECK-NOT: .init!
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable GrandchildOfInheritedInits {
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC6nativeACSi_tcfc
|
||||
// CHECK: #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC4objcACSi_tcfc
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC6nativeACSi_tcfC
|
||||
// CHECK: #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC4objcACSi_tcfC
|
||||
// CHECK-NOT: .init!
|
||||
// CHECK: }
|
||||
|
||||
@@ -551,6 +551,6 @@ public class ConcreteDerived : GenericBase<Int> {
|
||||
// Dynamic thunk + vtable re-abstraction
|
||||
// CHECK-LABEL: sil_vtable [serialized] ConcreteDerived {
|
||||
// CHECK-NEXT: #GenericBase.method!1: <T> (GenericBase<T>) -> (T) -> () : public @$S7dynamic15ConcreteDerivedC6methodyySiFAA11GenericBaseCADyyxFTV [override] // vtable thunk for dynamic.GenericBase.method(A) -> () dispatching to dynamic.ConcreteDerived.method(Swift.Int) -> ()
|
||||
// CHECK-NEXT: #GenericBase.init!initializer.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$S7dynamic15ConcreteDerivedCACycfc [override] // dynamic.ConcreteDerived.init() -> dynamic.ConcreteDerived
|
||||
// CHECK-NEXT: #GenericBase.init!allocator.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$S7dynamic15ConcreteDerivedCACycfC [override]
|
||||
// CHECK-NEXT: #ConcreteDerived.deinit!deallocator.1: @$S7dynamic15ConcreteDerivedCfD // dynamic.ConcreteDerived.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -882,13 +882,13 @@ func testOptionalTryNeverFailsAddressOnlyVar<T>(_ obj: T) {
|
||||
class SomeErrorClass : Error { }
|
||||
|
||||
// CHECK-LABEL: sil_vtable SomeErrorClass
|
||||
// CHECK-NEXT: #SomeErrorClass.init!initializer.1: {{.*}} : @$S6errors14SomeErrorClassCACycfc
|
||||
// CHECK-NEXT: #SomeErrorClass.init!allocator.1: {{.*}} : @$S6errors14SomeErrorClassCACycfC
|
||||
// CHECK-NEXT: #SomeErrorClass.deinit!deallocator.1: @$S6errors14SomeErrorClassCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
class OtherErrorSub : OtherError { }
|
||||
|
||||
// CHECK-LABEL: sil_vtable OtherErrorSub {
|
||||
// CHECK-NEXT: #OtherError.init!initializer.1: {{.*}} : @$S6errors13OtherErrorSubCACycfc [override] // OtherErrorSub.init()
|
||||
// CHECK-NEXT: #OtherError.init!allocator.1: {{.*}} : @$S6errors13OtherErrorSubCACycfC [override]
|
||||
// CHECK-NEXT: #OtherErrorSub.deinit!deallocator.1: @$S6errors13OtherErrorSubCfD // OtherErrorSub.__deallocating_deinit
|
||||
// CHECK-NEXT:}
|
||||
|
||||
@@ -33,13 +33,13 @@ func testDirectDispatch(c : TestClass) -> Int {
|
||||
// Verify that the non-overriding final methods don't get emitted to the vtable.
|
||||
// CHECK-LABEL: sil_vtable TestClass {
|
||||
// CHECK-NEXT: #TestClass.baseMethod!1: {{.*}} : @$S5final9TestClassC10baseMethod{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK-NEXT: #TestClass.init!initializer.1: {{.*}} : @$S5final9TestClassC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-NEXT: #TestClass.init!allocator.1: {{.*}} : @$S5final9TestClassC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK-NEXT: #TestClass.deinit!
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// Verify that overriding final methods don't get emitted to the vtable.
|
||||
// CHECK-LABEL: sil_vtable TestDerived {
|
||||
// CHECK-NEXT: #TestClass.baseMethod!1: {{.*}} : @$S5final11TestDerivedC10baseMethod{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK-NEXT: #TestClass.init!initializer.1: {{.*}} : @$S5final11TestDerivedC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-NEXT: #TestClass.init!allocator.1: {{.*}} : @$S5final11TestDerivedC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK-NEXT: #TestDerived.deinit!
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -54,7 +54,7 @@ public func useClass(d: Double, opts: SomeClass.Options) {
|
||||
}
|
||||
|
||||
extension SomeClass {
|
||||
// CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC16import_as_memberE6doubleABSd_tcfc
|
||||
// CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC16import_as_memberE6doubleABSd_tcfC
|
||||
// CHECK: bb0([[DOUBLE:%[0-9]+]] : @trivial $Double
|
||||
// CHECK-NOT: value_metatype
|
||||
// CHECK: [[FNREF:%[0-9]+]] = function_ref @MakeIAMSomeClass
|
||||
|
||||
@@ -85,18 +85,16 @@ struct S2 {
|
||||
class C1 {
|
||||
var ivar: X
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C1C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (X, @owned C1) -> @owned C1
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C1C{{[_0-9a-zA-Z]*}}fC
|
||||
convenience init(x: X) {
|
||||
// CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[ORIG_SELF:%[0-9]+]] : @owned $C1):
|
||||
// CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[SELF_META:%[0-9]+]] : @trivial $@thick C1.Type):
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var C1 }
|
||||
// CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
|
||||
// CHECK: store [[ORIG_SELF]] to [init] [[PB]] : $*C1
|
||||
// CHECK: [[SELF_FROM_BOX:%[0-9]+]] = load [take] [[PB]] : $*C1
|
||||
// CHECK: [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_FROM_BOX]] : $C1, #C1.init!initializer.1 : (C1.Type) -> (X, X) -> C1, $@convention(method) (X, X, @owned C1) -> @owned C1
|
||||
// CHECK: [[SELFP:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_FROM_BOX]]) : $@convention(method) (X, X, @owned C1) -> @owned C1
|
||||
// CHECK: store [[SELFP]] to [init] [[PB]] : $*C1
|
||||
// CHECK: [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick C1.Type, #C1.init!allocator.1
|
||||
// CHECK: [[SELFP:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_META]])
|
||||
// CHECK: assign [[SELFP]] to [[PB]]
|
||||
// CHECK: [[SELFP:%[0-9]+]] = load [copy] [[PB]] : $*C1
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]] : ${ var C1 }
|
||||
// CHECK: return [[SELFP]] : $C1
|
||||
@@ -109,17 +107,15 @@ class C1 {
|
||||
@objc class C2 {
|
||||
var ivar: X
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C2C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (X, @owned C2) -> @owned C2
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C2C{{[_0-9a-zA-Z]*}}fC
|
||||
convenience init(x: X) {
|
||||
// CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[ORIG_SELF:%[0-9]+]] : @owned $C2):
|
||||
// CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[SELF_META:%[0-9]+]] : @trivial $@thick C2.Type):
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var C2 }
|
||||
// CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_SELF:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[ORIG_SELF]] to [init] [[PB_SELF]] : $*C2
|
||||
// CHECK: [[SELF:%[0-9]+]] = load [take] [[PB_SELF]] : $*C2
|
||||
// CHECK: [[DELEG_INIT:%[0-9]+]] = class_method [[SELF]] : $C2, #C2.init!initializer.1 : (C2.Type) -> (X, X) -> C2, $@convention(method) (X, X, @owned C2) -> @owned C2
|
||||
// CHECK: [[REPLACE_SELF:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF]]) : $@convention(method) (X, X, @owned C2) -> @owned C2
|
||||
// CHECK: store [[REPLACE_SELF]] to [init] [[PB_SELF]] : $*C2
|
||||
// CHECK: [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick C2.Type, #C2.init!allocator.1
|
||||
// CHECK: [[REPLACE_SELF:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_META]])
|
||||
// CHECK: assign [[REPLACE_SELF]] to [[PB_SELF]] : $*C2
|
||||
// CHECK: [[VAR_15:%[0-9]+]] = load [copy] [[PB_SELF]] : $*C2
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]] : ${ var C2 }
|
||||
// CHECK: return [[VAR_15]] : $C2
|
||||
@@ -137,11 +133,11 @@ var x: X = X()
|
||||
class C3 {
|
||||
var i: Int = 5
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C3C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned C3) -> @owned C3
|
||||
// CHECK-LABEL: sil hidden @$S19init_ref_delegation2C3C{{[_0-9a-zA-Z]*}}fC
|
||||
convenience init() {
|
||||
// CHECK: mark_uninitialized [delegatingself]
|
||||
// CHECK-NOT: integer_literal
|
||||
// CHECK: class_method [[SELF:%[0-9]+]] : $C3, #C3.init!initializer.1 : (C3.Type) -> (X) -> C3, $@convention(method) (X, @owned C3) -> @owned C3
|
||||
// CHECK: class_method [[SELF:%[0-9]+]] : $@thick C3.Type, #C3.init!allocator.1
|
||||
// CHECK-NOT: integer_literal
|
||||
// CHECK: return
|
||||
self.init(x: x)
|
||||
@@ -158,9 +154,9 @@ extension C4 {
|
||||
convenience init(x1: X) {
|
||||
self.init()
|
||||
}
|
||||
// CHECK: sil hidden @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: [[PEER:%[0-9]+]] = function_ref @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: apply [[PEER]]([[X:%[0-9]+]], [[OBJ:%[0-9]+]])
|
||||
// CHECK: sil hidden @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: [[PEER:%[0-9]+]] = function_ref @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: apply [[PEER]]([[X:%[0-9]+]], [[META:%[0-9]+]])
|
||||
convenience init(x2: X) {
|
||||
self.init(x1: x2)
|
||||
}
|
||||
|
||||
@@ -358,20 +358,18 @@ class FailableBaseClass {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
|
||||
// CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfC
|
||||
// CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[OLD_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned FailableBaseClass
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]]
|
||||
// CHECK: [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
|
||||
// CHECK: br bb2([[RESULT]] : $Optional<FailableBaseClass>)
|
||||
// CHECK: bb2([[RESULT:%.*]] : @owned $Optional<FailableBaseClass>):
|
||||
// CHECK: return [[RESULT]]
|
||||
// CHECK: } // end sil function '$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc
|
||||
// CHECK-NEXT: }
|
||||
convenience init?(failAfterDelegation: ()) {
|
||||
self.init(noFail: ())
|
||||
return nil
|
||||
@@ -379,14 +377,12 @@ class FailableBaseClass {
|
||||
|
||||
// Optional to optional
|
||||
//
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
|
||||
// CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfC
|
||||
// CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[OLD_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass>
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
|
||||
// CHECK: cond_br {{.*}}, [[SUCC_BB:bb[0-9]+]], [[FAIL_BB:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[FAIL_BB:bb[0-9]+]]:
|
||||
@@ -395,7 +391,7 @@ class FailableBaseClass {
|
||||
//
|
||||
// CHECK: [[SUCC_BB]]:
|
||||
// CHECK: [[UNWRAPPED_NEW_SELF:%.*]] = unchecked_enum_data [[NEW_SELF]] : $Optional<FailableBaseClass>, #Optional.some!enumelt.1
|
||||
// CHECK: store [[UNWRAPPED_NEW_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK: assign [[UNWRAPPED_NEW_SELF]] to [[PB_BOX]]
|
||||
// CHECK: [[RESULT:%.*]] = load [copy] [[PB_BOX]]
|
||||
// CHECK: [[WRAPPED_RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.some!enumelt.1, [[RESULT]]
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]]
|
||||
@@ -414,23 +410,19 @@ class FailableBaseClass {
|
||||
|
||||
// IUO to optional
|
||||
//
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
|
||||
// CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfC
|
||||
// CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[OLD_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK-NEXT: [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
|
||||
// CHECK-NOT: [[OLD_SELF]]
|
||||
// CHECK-NOT: copy_value
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass>
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
|
||||
// CHECK: switch_enum [[NEW_SELF]] : $Optional<FailableBaseClass>, case #Optional.some!enumelt.1: [[SUCC_BB:bb[0-9]+]], case #Optional.none!enumelt: [[FAIL_BB:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[FAIL_BB]]:
|
||||
// CHECK: unreachable
|
||||
//
|
||||
// CHECK: [[SUCC_BB]]([[RESULT:%.*]] : @owned $FailableBaseClass):
|
||||
// CHECK: store [[RESULT]] to [init] [[PB_BOX]]
|
||||
// CHECK: assign [[RESULT]] to [[PB_BOX]]
|
||||
// CHECK: [[RESULT:%.*]] = load [copy] [[PB_BOX]]
|
||||
// CHECK: [[WRAPPED_RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.some!enumelt.1, [[RESULT]] : $FailableBaseClass
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]]
|
||||
@@ -438,7 +430,7 @@ class FailableBaseClass {
|
||||
//
|
||||
// CHECK: [[EPILOG_BB]]([[WRAPPED_RESULT:%.*]] : @owned $Optional<FailableBaseClass>):
|
||||
// CHECK: return [[WRAPPED_RESULT]]
|
||||
// CHECK: } // end sil function '$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfc'
|
||||
// CHECK-NEXT: }
|
||||
convenience init!(failDuringDelegation2: ()) {
|
||||
self.init(failBeforeFullInitialization: ())! // unnecessary-but-correct '!'
|
||||
}
|
||||
@@ -875,26 +867,23 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try unwrap(chainingFailAfterDelegation)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC39chainingFailDuringDelegationArgEmission0fghI4CallACSi_SitKcfc : $@convention(method) (Int, Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error) {
|
||||
// CHECK: bb0({{.*}}, [[OLD_SELF:%.*]] : @owned $ThrowDerivedClass):
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC39chainingFailDuringDelegationArgEmission0fghI4CallACSi_SitKcfC
|
||||
// CHECK: bb0({{.*}}, [[SELF_META:%.*]] : @trivial $@thick ThrowDerivedClass.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var ThrowDerivedClass }, let, name "self"
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[OLD_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[MOVE_ONLY_SELF:%.*]] = load [take] [[PB_BOX]]
|
||||
// CHECK: try_apply {{.*}}({{.*}}) : $@convention(thin) (Int) -> (Int, @error Error), normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[SUCC_BB1]](
|
||||
// CHECK: try_apply {{.*}}({{.*}}, [[MOVE_ONLY_SELF]]) : $@convention(method) (Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error), normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
|
||||
// CHECK: try_apply {{.*}}({{.*}}, [[SELF_META]]) : {{.*}}, normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[SUCC_BB2]]([[NEW_SELF:%.*]] : @owned $ThrowDerivedClass):
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK-NEXT: assign [[NEW_SELF]] to [[PB_BOX]]
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = load [copy] [[PB_BOX]]
|
||||
// CHECK-NEXT: destroy_value [[MARKED_SELF_BOX]]
|
||||
// CHECK-NEXT: return [[RESULT]]
|
||||
//
|
||||
// CHECK: [[ERROR_BB1]]([[ERROR:%.*]] : @owned $Error):
|
||||
// CHECK-NEXT: store [[MOVE_ONLY_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK-NEXT: br [[THROWING_BB:bb[0-9]+]]([[ERROR]]
|
||||
//
|
||||
// CHECK: [[ERROR_BB2]]([[ERROR:%.*]] : @owned $Error):
|
||||
@@ -912,17 +901,15 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try unwrap(chainingFailAfterDelegation)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC32chainingFailDuringDelegationCall0fg5AfterI0ACSi_SitKcfc : $@convention(method) (Int, Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error) {
|
||||
// CHECK: bb0({{.*}}, [[OLD_SELF:%.*]] : @owned $ThrowDerivedClass):
|
||||
// CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC32chainingFailDuringDelegationCall0fg5AfterI0ACSi_SitKcfC
|
||||
// CHECK: bb0({{.*}}, [[SELF_META:%.*]] : @trivial $@thick ThrowDerivedClass.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var ThrowDerivedClass }, let, name "self"
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[OLD_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[MOVE_ONLY_SELF:%.*]] = load [take] [[PB_BOX]]
|
||||
// CHECK: try_apply {{.*}}([[MOVE_ONLY_SELF]]) : $@convention(method) (@owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error), normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
|
||||
// CHECK: try_apply {{.*}}([[SELF_META]]) : {{.*}}, normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[SUCC_BB1]]([[NEW_SELF:%.*]] : @owned $ThrowDerivedClass):
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [init] [[PB_BOX]]
|
||||
// CHECK-NEXT: assign [[NEW_SELF]] to [[PB_BOX]]
|
||||
// CHECK-NEXT: // function_ref
|
||||
// CHECK-NEXT: function_ref @
|
||||
// CHECK-NEXT: try_apply {{.*}}({{.*}}) : $@convention(thin) (Int) -> (Int, @error Error), normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
|
||||
|
||||
@@ -34,7 +34,7 @@ class DerivedClassWithNonTrivialProperties : RootClassWithoutProperties {
|
||||
// CHECK-NEXT: return [[RESULT]]
|
||||
|
||||
// CHECK-LABEL: sil_vtable RootClassWithoutProperties {
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!initializer.1
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!allocator.1
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.deinit!deallocator
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -45,7 +45,7 @@ class DerivedClassWithNonTrivialProperties : RootClassWithoutProperties {
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.y!getter.1
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.y!setter.1
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.y!modify.1
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.init!initializer.1
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.init!allocator.1
|
||||
// CHECK-NEXT: #RootClassWithTrivialProperties.deinit!deallocator
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -53,12 +53,12 @@ class DerivedClassWithNonTrivialProperties : RootClassWithoutProperties {
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.x!getter.1
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.x!setter.1
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.x!modify.1
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.init!initializer.1
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.init!allocator.1
|
||||
// CHECK-NEXT: #RootClassWithNonTrivialProperties.deinit!deallocator
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable DerivedClassWithTrivialProperties {
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!initializer.1
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!allocator.1
|
||||
// CHECK-NEXT: #DerivedClassWithTrivialProperties.z!getter.1
|
||||
// CHECK-NEXT: #DerivedClassWithTrivialProperties.z!setter.1
|
||||
// CHECK-NEXT: #DerivedClassWithTrivialProperties.z!modify.1
|
||||
@@ -66,7 +66,7 @@ class DerivedClassWithNonTrivialProperties : RootClassWithoutProperties {
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable DerivedClassWithNonTrivialProperties {
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!initializer.1
|
||||
// CHECK-NEXT: #RootClassWithoutProperties.init!allocator.1
|
||||
// CHECK-NEXT: #DerivedClassWithNonTrivialProperties.z!getter.1
|
||||
// CHECK-NEXT: #DerivedClassWithNonTrivialProperties.z!setter.1
|
||||
// CHECK-NEXT: #DerivedClassWithNonTrivialProperties.z!modify.1
|
||||
|
||||
@@ -36,10 +36,10 @@ final class Bobamathing: Thingamabob {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil private [transparent] [thunk] @$S{{.*}}GadgetC{{.*}}CTW
|
||||
// CHECK: class_method {{%.*}} : $@thick Gadget.Type, #Gadget.init!allocator.1 :
|
||||
// CHECK: function_ref @{{.*}}Gadget{{.*}}fC :
|
||||
|
||||
// CHECK-LABEL: sil_vtable Gadget {
|
||||
// CHECK: #Gadget.init!allocator.1: (Gadget.Type) -> () -> Gadget : @$S{{.*}}GadgetC{{.*}}C //
|
||||
// CHECK-NOT: #Gadget.init!allocator.1
|
||||
|
||||
// CHECK-LABEL: sil_vtable Gizmo {
|
||||
// CHECK: #Gadget.init!allocator.1: (Gadget.Type) -> () -> Gadget : @$S{{.*}}GizmoC{{.*}}C [override] //
|
||||
// CHECK-NOT: #Gadget.init!allocator.1
|
||||
|
||||
@@ -21,15 +21,11 @@ extension Hive {
|
||||
// not a convenience initializer, which means it does not have an initializing
|
||||
// entry point at all.
|
||||
|
||||
// CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfc : $@convention(method) (@owned Bee, @owned Hive) -> @owned Hive {
|
||||
// CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[OLD_HIVE:%.*]] : @owned $Hive):
|
||||
// CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfC
|
||||
// CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[META:%.*]] : @trivial $@thick Hive.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var Hive }, let, name "self"
|
||||
// CHECK: [[MU:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MU]] : ${ var Hive }, 0
|
||||
// CHECK: store [[OLD_HIVE]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[BORROWED_SELF:%.*]] = load_borrow [[PB_BOX]]
|
||||
// CHECK: [[META:%[0-9]+]] = value_metatype $@thick Hive.Type, [[BORROWED_SELF]] : $Hive
|
||||
// CHECK: end_borrow [[BORROWED_SELF]]
|
||||
// CHECK: [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]] : $@thick Hive.Type to $@objc_metatype Hive.Type
|
||||
// CHECK: [[BORROWED_QUEEN:%.*]] = begin_borrow [[QUEEN]]
|
||||
// CHECK: [[COPIED_BORROWED_QUEEN:%.*]] = copy_value [[BORROWED_QUEEN]]
|
||||
@@ -42,58 +38,36 @@ extension Hive {
|
||||
//
|
||||
// CHECK: [[SOME_BB]]([[NEW_HIVE:%.*]] : @owned $Hive):
|
||||
// CHECK: assign [[NEW_HIVE]] to [[PB_BOX]]
|
||||
// CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfc'
|
||||
// CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfC'
|
||||
convenience init(otherQueen other: Bee) {
|
||||
self.init(queen: other)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE15otherFlakyQueenABSo3BeeC_tKcfC : $@convention(method) (@owned Bee, @thick Hive.Type) -> (@owned Hive, @error Error) {
|
||||
// CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[METATYPE:%.*]] : @trivial $@thick Hive.Type):
|
||||
// CHECK: [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[METATYPE]]
|
||||
// CHECK: [[HIVE:%.*]] = alloc_ref_dynamic [objc] [[OBJC_METATYPE]]
|
||||
// CHECK: try_apply {{.*}}([[QUEEN]], [[HIVE]]) : $@convention(method) (@owned Bee, @owned Hive) -> (@owned Hive, @error Error), normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
|
||||
//
|
||||
// CHECK: [[NORMAL_BB]]([[HIVE:%.*]] : @owned $Hive):
|
||||
// CHECK: return [[HIVE]]
|
||||
//
|
||||
// CHECK: [[ERROR_BB]]([[ERROR:%.*]] : @owned $Error):
|
||||
// CHECK: builtin "willThrow"([[ERROR]] : $Error)
|
||||
// CHECK: throw [[ERROR]]
|
||||
// CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE15otherFlakyQueenABSo3BeeC_tKcfC'
|
||||
convenience init(otherFlakyQueen other: Bee) throws {
|
||||
try self.init(flakyQueen: other)
|
||||
}
|
||||
}
|
||||
|
||||
extension SomeClass {
|
||||
// CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfc : $@convention(method) (Double, @owned SomeClass) -> @owned SomeClass {
|
||||
// CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfC
|
||||
// CHECK: bb0([[DOUBLE:%.*]] : @trivial $Double,
|
||||
// CHECK-NOT: value_metatype
|
||||
// CHECK: [[FNREF:%[0-9]+]] = function_ref @MakeIAMSomeClass
|
||||
// CHECK: apply [[FNREF]]([[DOUBLE]])
|
||||
// CHECK: } // end sil function '$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfc'
|
||||
convenience init(double: Double) {
|
||||
self.init(value: double)
|
||||
}
|
||||
}
|
||||
|
||||
class SubHive : Hive {
|
||||
// CHECK-LABEL: sil hidden @$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfc : $@convention(method) (@owned SubHive) -> @owned SubHive {
|
||||
// CHECK: bb0([[SUBHIVE:%.*]] : @owned $SubHive):
|
||||
// CHECK-LABEL: sil hidden @$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfC
|
||||
// CHECK: bb0([[METATYPE:%.*]] : @trivial $@thick SubHive.Type):
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var SubHive }, let, name "self"
|
||||
// CHECK: [[MU:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]] : ${ var SubHive }
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MU]] : ${ var SubHive }, 0
|
||||
// CHECK: store [[SUBHIVE]] to [init] [[PB_BOX]]
|
||||
// CHECK: [[BORROWED_SELF:%.*]] = load_borrow [[PB_BOX]]
|
||||
// CHECK: [[UPCAST_BORROWED_SELF:%.*]] = upcast [[BORROWED_SELF]] : $SubHive to $Hive
|
||||
// CHECK: [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[UPCAST_BORROWED_SELF:%.*]]
|
||||
// CHECK: end_borrow [[BORROWED_SELF]]
|
||||
// CHECK: [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[METATYPE]]
|
||||
// CHECK: [[UP_METATYPE:%.*]] = upcast [[METATYPE]]
|
||||
// CHECK: [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[UP_METATYPE]]
|
||||
// CHECK: [[QUEEN:%.*]] = unchecked_ref_cast {{.*}} : $Bee to $Optional<Bee>
|
||||
// CHECK: [[HIVE_INIT_FN:%.*]] = objc_method [[OBJC_METATYPE]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign
|
||||
// CHECK: apply [[HIVE_INIT_FN]]([[QUEEN]], [[OBJC_METATYPE]]) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
|
||||
// CHECK: destroy_value [[QUEEN]]
|
||||
// CHECK: } // end sil function '$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfc'
|
||||
// CHECK: } // end sil function '$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfC'
|
||||
convenience init(delegatesToInherited: ()) {
|
||||
self.init(queen: Bee())
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
import gizmo
|
||||
|
||||
extension Gizmo {
|
||||
// CHECK-LABEL: sil hidden @$SSo5GizmoC24objc_init_ref_delegationE{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-LABEL: sil hidden @$SSo5GizmoC24objc_init_ref_delegationE{{[_0-9a-zA-Z]*}}fC
|
||||
convenience init(int i: Int) {
|
||||
// CHECK: bb0([[I:%[0-9]+]] : @trivial $Int, [[ORIG_SELF:%[0-9]+]] : @owned $Gizmo):
|
||||
// CHECK: bb0([[I:%[0-9]+]] : @trivial $Int, [[SELF_META:%[0-9]+]] : @trivial $@thick Gizmo.Type):
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var Gizmo }
|
||||
// CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: store [[ORIG_SELF]] to [init] [[PB_BOX]] : $*Gizmo
|
||||
// CHECK: [[SELF:%[0-9]+]] = load [take] [[PB_BOX]] : $*Gizmo
|
||||
// CHECK: [[INIT_DELEG:%[0-9]+]] = objc_method [[SELF]] : $Gizmo, #Gizmo.init!initializer.1.foreign : (Gizmo.Type) -> (Int) -> Gizmo?, $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
|
||||
// CHECK: [[SELF_RET:%[0-9]+]] = apply [[INIT_DELEG]]([[I]], [[SELF]]) : $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
|
||||
// CHECK: [[SELF_OBJC_META:%.*]] = thick_to_objc_metatype [[SELF_META]]
|
||||
// CHECK: [[ORIG_SELF:%.*]] = alloc_ref_dynamic [objc] [[SELF_OBJC_META]]
|
||||
// CHECK: [[INIT_DELEG:%[0-9]+]] = objc_method [[ORIG_SELF]] : $Gizmo, #Gizmo.init!initializer.1.foreign : (Gizmo.Type) -> (Int) -> Gizmo?, $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
|
||||
// CHECK: [[SELF_RET:%[0-9]+]] = apply [[INIT_DELEG]]([[I]], [[ORIG_SELF]]) : $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
|
||||
// CHECK: [[SELF4:%.*]] = load [copy] [[PB_BOX]]
|
||||
// CHECK: destroy_value [[MARKED_SELF_BOX]]
|
||||
// CHECK: return [[SELF4]] : $Gizmo
|
||||
|
||||
@@ -23,17 +23,21 @@ class Root {
|
||||
@objc dynamic required init() {}
|
||||
}
|
||||
|
||||
// Because these init() hierarchies are all rooted in overriding
|
||||
// -[NSObject init], they're all dynamic whether explicitly declared so or not,
|
||||
// so do not appear in the vtable.
|
||||
|
||||
// CHECK-LABEL: sil_vtable Baboom {
|
||||
// CHECK: #Boom.init!allocator.1: (Boom.Type) -> () -> Boom : @$S29objc_required_designated_init6BaboomCACycfC [override]
|
||||
// CHECK: #Baboom.deinit!deallocator.1: @$S29objc_required_designated_init6BaboomCfD
|
||||
// CHECK-NOT: #Boom.init!allocator.1: (Boom.Type) -> () -> Boom : @$S29objc_required_designated_init6BaboomCACycfC [override]
|
||||
// CHECK: #Baboom.deinit!deallocator.1: @$S29objc_required_designated_init6BaboomCfD
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable BigBadaBoom {
|
||||
// CHECK: #Badaboom.init!allocator.1: <U> (Badaboom<U>.Type) -> () -> Badaboom<U> : @$S29objc_required_designated_init11BigBadaBoomCACyxGycfC [override]
|
||||
// CHECK: #BigBadaBoom.deinit!deallocator.1: @$S29objc_required_designated_init11BigBadaBoomCfD
|
||||
// CHECK-NOT: #Badaboom.init!allocator.1
|
||||
// CHECK: #BigBadaBoom.deinit!deallocator.1: @$S29objc_required_designated_init11BigBadaBoomCfD
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable Root {
|
||||
// CHECK: #Root.init!allocator.1: (Root.Type) -> () -> Root : @$S29objc_required_designated_init4RootCACycfC
|
||||
// CHECK: #Root.deinit!deallocator.1: @$S29objc_required_designated_init4RootCfD
|
||||
// CHECK-NOT: #Root.init!allocator.1
|
||||
// CHECK: #Root.deinit!deallocator.1: @$S29objc_required_designated_init4RootCfD
|
||||
// CHECK: }
|
||||
|
||||
@@ -469,17 +469,9 @@ extension Hoozit {
|
||||
// CHECK-LABEL: sil hidden [thunk] @$S11objc_thunks6HoozitC3intACSi_tcfcTo : $@convention(objc_method) (Int, @owned Hoozit) -> @owned Hoozit
|
||||
@objc dynamic convenience init(int i: Int) { self.init(bellsOn: i) }
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S11objc_thunks6HoozitC6doubleACSd_tcfc : $@convention(method) (Double, @owned Hoozit) -> @owned Hoozit
|
||||
// CHECK-LABEL: sil hidden @$S11objc_thunks6HoozitC6doubleACSd_tcfC : $@convention(method) (Double, @thick Hoozit.Type) -> @owned Hoozit
|
||||
convenience init(double d: Double) {
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var Hoozit }
|
||||
// CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: [[X_BOX:%[0-9]+]] = alloc_box ${ var X }
|
||||
var x = X()
|
||||
// CHECK: [[CTOR:%[0-9]+]] = objc_method [[SELF:%[0-9]+]] : $Hoozit, #Hoozit.init!initializer.1.foreign : (Hoozit.Type) -> (Int) -> Hoozit, $@convention(objc_method) (Int, @owned Hoozit) -> @owned Hoozit
|
||||
// CHECK: [[NEW_SELF:%[0-9]+]] = apply [[CTOR]]
|
||||
// CHECK: store [[NEW_SELF]] to [init] [[PB_BOX]] : $*Hoozit
|
||||
// CHECK: return
|
||||
self.init(int:Int(d))
|
||||
other()
|
||||
}
|
||||
|
||||
@@ -823,11 +823,9 @@ extension ProtoDelegatesToObjC where Self : ObjCInitClass {
|
||||
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : ObjCInitClass, τ_0_0 : ProtoDelegatesToObjC> { var τ_0_0 } <Self>
|
||||
// CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_SELF_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: [[SELF_META_OBJC:%[0-9]+]] = thick_to_objc_metatype [[SELF_META]] : $@thick Self.Type to $@objc_metatype Self.Type
|
||||
// CHECK: [[SELF_ALLOC:%[0-9]+]] = alloc_ref_dynamic [objc] [[SELF_META_OBJC]] : $@objc_metatype Self.Type, $Self
|
||||
// CHECK: [[SELF_ALLOC_C:%[0-9]+]] = upcast [[SELF_ALLOC]] : $Self to $ObjCInitClass
|
||||
// CHECK: [[OBJC_INIT:%[0-9]+]] = class_method [[SELF_ALLOC_C]] : $ObjCInitClass, #ObjCInitClass.init!initializer.1 : (ObjCInitClass.Type) -> () -> ObjCInitClass, $@convention(method) (@owned ObjCInitClass) -> @owned ObjCInitClass
|
||||
// CHECK: [[SELF_RESULT:%[0-9]+]] = apply [[OBJC_INIT]]([[SELF_ALLOC_C]]) : $@convention(method) (@owned ObjCInitClass) -> @owned ObjCInitClass
|
||||
// CHECK: [[SELF_META_C:%[0-9]+]] = upcast [[SELF_META]] : $@thick Self.Type to $@thick ObjCInitClass.Type
|
||||
// CHECK: [[OBJC_INIT:%[0-9]+]] = class_method [[SELF_META_C]] : $@thick ObjCInitClass.Type, #ObjCInitClass.init!allocator.1
|
||||
// CHECK: [[SELF_RESULT:%[0-9]+]] = apply [[OBJC_INIT]]([[SELF_META_C]])
|
||||
// CHECK: [[SELF_RESULT_AS_SELF:%[0-9]+]] = unchecked_ref_cast [[SELF_RESULT]] : $ObjCInitClass to $Self
|
||||
// CHECK: assign [[SELF_RESULT_AS_SELF]] to [[PB_SELF_BOX]] : $*Self
|
||||
self.init()
|
||||
|
||||
@@ -19,8 +19,6 @@ class Bar: Foo {
|
||||
|
||||
// CHECK-LABEL: sil_vtable Foo {
|
||||
// CHECK: #Foo.init!allocator.1: {{.*}} : @$S13required_init3FooC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: #Foo.init!initializer.1: {{.*}} : @$S13required_init3FooC{{[_0-9a-zA-Z]*}}fc
|
||||
|
||||
// CHECK-LABEL: sil_vtable Bar {
|
||||
// CHECK: #Foo.init!allocator.1: {{.*}} : @$S13required_init3BarC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: #Foo.init!initializer.1: {{.*}} : @$S13required_init3BarC{{[_0-9a-zA-Z]*}}fc
|
||||
|
||||
@@ -27,15 +27,13 @@ class Bar: Foo {
|
||||
}
|
||||
|
||||
extension Foo {
|
||||
// CHECK-LABEL: sil hidden @$S22super_init_refcounting3FooC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-LABEL: sil hidden @$S22super_init_refcounting3FooC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_box ${ var Foo }
|
||||
// CHECK: [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
|
||||
// CHECK: [[PB_SELF_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
|
||||
// CHECK: [[ORIG_SELF:%.*]] = load [take] [[PB_SELF_BOX]]
|
||||
// CHECK-NOT: copy_value [[ORIG_SELF]]
|
||||
// CHECK: [[SUPER_INIT:%.*]] = class_method
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply [[SUPER_INIT]]([[ORIG_SELF]])
|
||||
// CHECK: store [[NEW_SELF]] to [init] [[PB_SELF_BOX]]
|
||||
// CHECK: [[SELF_INIT:%.*]] = class_method
|
||||
// CHECK: [[NEW_SELF:%.*]] = apply [[SELF_INIT]](%1)
|
||||
// CHECK: assign [[NEW_SELF]] to [[PB_SELF_BOX]]
|
||||
convenience init(x: Int) {
|
||||
self.init()
|
||||
}
|
||||
|
||||
@@ -40,19 +40,19 @@ public class PublicSub: Base {
|
||||
|
||||
// CHECK-LABEL: sil_vtable PrivateSub {
|
||||
// CHECK-NEXT: #Base.foo!1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLC3fooyyF
|
||||
// CHECK-NEXT: #Base.init!initializer.1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCADycfc
|
||||
// CHECK-NEXT: #Base.init!allocator.1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCADycfC
|
||||
// CHECK-NEXT: #PrivateSub.deinit!deallocator.1: @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable Sub {
|
||||
// CHECK-NEXT: #Base.foo!1: {{.*}} : @$S4main3SubC3fooyyF
|
||||
// CHECK-NEXT: #Base.init!initializer.1: {{.*}} : @$S4main3SubCACycfc
|
||||
// CHECK-NEXT: #Base.init!allocator.1: {{.*}} : @$S4main3SubCACycfC
|
||||
// CHECK-NEXT: #Sub.deinit!deallocator.1: @$S4main3SubCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_vtable [serialized] PublicSub {
|
||||
// CHECK-NEXT: #Base.foo!1: {{.*}} : @$S4main9PublicSubC3fooyyF
|
||||
// CHECK-NEXT: #Base.init!initializer.1: {{.*}} : @$S4main9PublicSubCACycfc
|
||||
// CHECK-NEXT: #Base.init!allocator.1: {{.*}} : @$S4main9PublicSubCACycfC
|
||||
// CHECK-NEXT: #PublicSub.deinit!deallocator.1: @$S4main9PublicSubCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class Opaque<T> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction6OpaqueCACyxGycfc // Opaque.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction6OpaqueCACyxGycfC
|
||||
// CHECK-NEXT: #Opaque.deinit!deallocator.1: @$S27vtable_thunks_reabstraction6OpaqueCfD // Opaque.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -191,7 +191,7 @@ class StillOpaque<T>: Opaque<T> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction11StillOpaqueC24variantOptionalityTuples1xx_xm_xxcttx_xm_xxcttSg_tFAA0E0CAdeFx_xm_xxctt_tFTV [override] // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to StillOpaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11StillOpaqueCACyxGycfc [override] // StillOpaque.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11StillOpaqueCACyxGycfC [override]
|
||||
|
||||
// Tuple becomes more optional -- needs new vtable entry
|
||||
|
||||
@@ -222,7 +222,7 @@ class ConcreteValue: Opaque<S> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC27variantOptionalityMetatypes1xAA1SVmAGmSg_tFAA6OpaqueCAdExmSgxm_tFTV [override] // vtable thunk for Opaque.variantOptionalityMetatypes(x:) dispatching to ConcreteValue.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC27variantOptionalityFunctions1xAA1SVAGcA2GcSg_tFAA6OpaqueCAdExxcSgxxc_tFTV [override] // vtable thunk for Opaque.variantOptionalityFunctions(x:) dispatching to ConcreteValue.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC24variantOptionalityTuples1xAA1SV_AGm_A2GcttAG_AGm_A2GcttSg_tFAA6OpaqueCAdEx_xm_xxcttSgx_xm_xxctt_tFTV [override] // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to ConcreteValue.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteValueCACycfc [override] // ConcreteValue.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteValueCACycfC [override]
|
||||
|
||||
// Value types becoming more optional -- needs new vtable entry
|
||||
|
||||
@@ -255,7 +255,7 @@ class ConcreteClass: Opaque<C> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction13ConcreteClassC27variantOptionalityMetatypes1xAA1CCmAGmSg_tF [override] // ConcreteClass.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : hidden @$S27vtable_thunks_reabstraction13ConcreteClassC27variantOptionalityFunctions1xAA1CCAGcA2GcSg_tFAA6OpaqueCAdExxcSgxxc_tFTV [override] // vtable thunk for Opaque.variantOptionalityFunctions(x:) dispatching to ConcreteClass.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction13ConcreteClassC24variantOptionalityTuples1xAA1CC_AGm_A2GcttAG_AGm_A2GcttSg_tFAA6OpaqueCAdEx_xm_xxcttSgx_xm_xxctt_tFTV [override] // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to ConcreteClass.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteClassCACycfc [override] // ConcreteClass.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteClassCACycfC [override]
|
||||
|
||||
// Class references are ABI-compatible with optional class references, and
|
||||
// similarly for class metatypes.
|
||||
@@ -284,7 +284,7 @@ class ConcreteClassVariance: Opaque<C> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassVarianceCACycfc [override] // ConcreteClassVariance.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassVarianceCACycfC [override]
|
||||
|
||||
// No new vtable entries -- class references are ABI compatible with
|
||||
// optional class references.
|
||||
@@ -307,7 +307,7 @@ class OpaqueTuple<U>: Opaque<(U, U)> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11OpaqueTupleCACyxGycfc [override] // OpaqueTuple.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11OpaqueTupleCACyxGycfC [override]
|
||||
|
||||
// Optionality change of tuple.
|
||||
|
||||
@@ -331,7 +331,7 @@ class ConcreteTuple: Opaque<(S, S)> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteTupleCACycfc [override] // ConcreteTuple.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteTupleCACycfC [override]
|
||||
|
||||
// Optionality change of tuple.
|
||||
|
||||
@@ -355,7 +355,7 @@ class OpaqueFunction<U, V>: Opaque<(U) -> V> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueFunctionCACyxq_Gycfc [override] // OpaqueFunction.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueFunctionCACyxq_GycfC [override]
|
||||
|
||||
// Optionality change of function.
|
||||
|
||||
@@ -379,7 +379,7 @@ class ConcreteFunction: Opaque<(S) -> S> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteFunctionCACycfc [override] // ConcreteFunction.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteFunctionCACycfC [override]
|
||||
|
||||
// Optionality change of function.
|
||||
|
||||
@@ -403,7 +403,7 @@ class OpaqueMetatype<U>: Opaque<U.Type> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueMetatypeCACyxGycfc [override] // OpaqueMetatype.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueMetatypeCACyxGycfC [override]
|
||||
|
||||
// Optionality change of metatype.
|
||||
|
||||
@@ -427,7 +427,7 @@ class ConcreteValueMetatype: Opaque<S.Type> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteValueMetatypeCACycfc [override] // ConcreteValueMetatype.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteValueMetatypeCACycfC [override]
|
||||
|
||||
// Optionality change of metatype.
|
||||
|
||||
@@ -451,7 +451,7 @@ class ConcreteClassMetatype: Opaque<C.Type> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassMetatypeCACycfc [override] // ConcreteClassMetatype.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassMetatypeCACycfC [override]
|
||||
|
||||
// Class metatypes are ABI compatible with optional class metatypes.
|
||||
|
||||
@@ -475,7 +475,7 @@ class ConcreteOptional: Opaque<S?> {
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited] // Opaque.variantOptionalityMetatypes(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited] // Opaque.variantOptionalityFunctions(x:)
|
||||
// CHECK-NEXT: #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited] // Opaque.variantOptionalityTuples(x:)
|
||||
// CHECK-NEXT: #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteOptionalCACycfc [override] // ConcreteOptional.init()
|
||||
// CHECK-NEXT: #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteOptionalCACycfC [override]
|
||||
// CHECK-NEXT: #ConcreteOptional.deinit!deallocator.1: @$S27vtable_thunks_reabstraction16ConcreteOptionalCfD // ConcreteOptional.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -488,7 +488,7 @@ class GenericBase<T> {
|
||||
|
||||
// CHECK-LABEL: sil_vtable GenericBase {
|
||||
// CHECK-NEXT: #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction11GenericBaseC7doStuff1t1uyx_qd__tlF // GenericBase.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction11GenericBaseC1t1uACyxGx_qd__tclufc // GenericBase.init<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction11GenericBaseC1t1uACyxGx_qd__tclufC
|
||||
// CHECK-NEXT: #GenericBase.deinit!deallocator.1: @$S27vtable_thunks_reabstraction11GenericBaseCfD // GenericBase.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -503,7 +503,7 @@ class ConcreteSub : GenericBase<Int> {
|
||||
|
||||
// CHECK-LABEL: sil_vtable ConcreteSub {
|
||||
// CHECK-NEXT: #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC7doStuff1t1uySi_xtlFAA11GenericBaseCAdeFyx_qd__tlFTV [override] // vtable thunk for GenericBase.doStuff<A>(t:u:) dispatching to ConcreteSub.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC1t1uACSi_xtclufcAA11GenericBaseCAdeGyxGx_qd__tclufcTV [override] // vtable thunk for GenericBase.init<A>(t:u:) dispatching to ConcreteSub.init<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC1t1uACSi_xtclufCAA11GenericBaseCAdeGyxGx_qd__tclufCTV [override]
|
||||
// CHECK-NEXT: #ConcreteSub.deinit!deallocator.1: @$S27vtable_thunks_reabstraction11ConcreteSubCfD // ConcreteSub.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -513,7 +513,7 @@ class ConcreteBase {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil_vtable ConcreteBase {
|
||||
// CHECK-NEXT: #ConcreteBase.init!initializer.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction12ConcreteBaseC1t1uACSi_xtclufc // ConcreteBase.init<A>(t:u:)
|
||||
// CHECK-NEXT: #ConcreteBase.init!allocator.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction12ConcreteBaseC1t1uACSi_xtclufC
|
||||
// CHECK-NEXT: #ConcreteBase.doStuff!1: <U> (ConcreteBase) -> (Int, U) -> () : @$S27vtable_thunks_reabstraction12ConcreteBaseC7doStuff1t1uySi_xtlF // ConcreteBase.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #ConcreteBase.deinit!deallocator.1: @$S27vtable_thunks_reabstraction12ConcreteBaseCfD // ConcreteBase.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
@@ -528,7 +528,7 @@ class GenericSub<T> : ConcreteBase {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil_vtable GenericSub {
|
||||
// CHECK-NEXT: #ConcreteBase.init!initializer.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction10GenericSubC1t1uACyxGSi_qd__tclufc [override] // GenericSub.init<A>(t:u:)
|
||||
// CHECK-NEXT: #ConcreteBase.init!allocator.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction10GenericSubC1t1uACyxGSi_qd__tclufC [override]
|
||||
// CHECK-NEXT: #ConcreteBase.doStuff!1: <U> (ConcreteBase) -> (Int, U) -> () : @$S27vtable_thunks_reabstraction10GenericSubC7doStuff1t1uySi_qd__tlF [override] // GenericSub.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericSub.deinit!deallocator.1: @$S27vtable_thunks_reabstraction10GenericSubCfD // GenericSub.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
@@ -542,7 +542,7 @@ class MoreGenericSub1<T, TT> : GenericBase<T> {
|
||||
|
||||
// CHECK-LABEL: sil_vtable MoreGenericSub1 {
|
||||
// CHECK-NEXT: #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction15MoreGenericSub1C7doStuff1t1uyx_qd__tlF [override] // MoreGenericSub1.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub1C1t1uACyxq_Gx_qd__tclufc [override] // MoreGenericSub1.init<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub1C1t1uACyxq_Gx_qd__tclufC [override]
|
||||
// CHECK-NEXT: #MoreGenericSub1.deinit!deallocator.1: @$S27vtable_thunks_reabstraction15MoreGenericSub1CfD // MoreGenericSub1.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -554,6 +554,6 @@ class MoreGenericSub2<TT, T> : GenericBase<T> {
|
||||
|
||||
// CHECK-LABEL: sil_vtable MoreGenericSub2 {
|
||||
// CHECK-NEXT: #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction15MoreGenericSub2C7doStuff1t1uyq__qd__tlF [override] // MoreGenericSub2.doStuff<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufc [override] // MoreGenericSub2.init<A>(t:u:)
|
||||
// CHECK-NEXT: #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufC [override]
|
||||
// CHECK-NEXT: #MoreGenericSub2.deinit!deallocator.1: @$S27vtable_thunks_reabstraction15MoreGenericSub2CfD // MoreGenericSub2.__deallocating_deinit
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -21,7 +21,6 @@ class C : B {
|
||||
// CHECK: #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #A.qux!1: {{.*}} : @$S7vtables1CC3qux{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #B.init!allocator.1: {{.*}} : @$S7vtables1CC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: #B.init!initializer.1: {{.*}} : @$S7vtables1CC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: #B.zim!1: {{.*}} : @$S7vtables1BC3zim{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #B.zang!1: {{.*}} : @$S7vtables1CC4zang{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #C.flopsy!1: {{.*}} : @$S7vtables1CC6flopsy{{[_0-9a-zA-Z]*}}F
|
||||
@@ -40,7 +39,7 @@ class A {
|
||||
// CHECK: #A.bar!1: {{.*}} : @$S7vtables1AC3bar{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #A.qux!1: {{.*}} : @$S7vtables1AC3qux{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #A.init!initializer.1: {{.*}} : @$S7vtables1AC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: #A.init!allocator.1: {{.*}} : @$S7vtables1AC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: }
|
||||
|
||||
class B : A {
|
||||
@@ -61,14 +60,12 @@ class B : A {
|
||||
// CHECK: #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #A.qux!1: {{.*}} : @$S7vtables1BC3qux{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #B.init!allocator.1: {{.*}} : @$S7vtables1BC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: #B.init!initializer.1: {{.*}} : @$S7vtables1BC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: #B.zim!1: {{.*}} : @$S7vtables1BC3zim{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: #B.zang!1: {{.*}} : @$S7vtables1BC4zang{{[_0-9a-zA-Z]*}}F
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: sil_vtable RequiredInitDerived {
|
||||
// CHECK-NEXT: #SimpleInitBase.init!initializer.1: {{.*}} : @$S7vtables19RequiredInitDerivedC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK-NEXT: #RequiredInitDerived.init!allocator.1: {{.*}} : @$S7vtables19RequiredInitDerivedC
|
||||
// CHECK-NEXT: #SimpleInitBase.init!allocator.1: {{.*}} : @$S7vtables19RequiredInitDerivedC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK-NEXT: #RequiredInitDerived.deinit!deallocator.1: @$S7vtables19RequiredInitDerivedCfD
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ func callWotsit(_ w: Wotsit) {
|
||||
|
||||
// <rdar://problem/15282548>
|
||||
// CHECK: sil_vtable Base {
|
||||
// CHECK: #Base.init!initializer.1: {{.*}} : @$S12vtables_objc4BaseC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: #Base.init!allocator.1: {{.*}} : @$S12vtables_objc4BaseC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: }
|
||||
// CHECK: sil_vtable Derived {
|
||||
// CHECK: #Base.init!initializer.1: {{.*}} : @$S12vtables_objc7DerivedC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: #Base.init!allocator.1: {{.*}} : @$S12vtables_objc7DerivedC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: }
|
||||
@objc class Base {}
|
||||
|
||||
|
||||
@@ -36,10 +36,11 @@ protocol Initable {
|
||||
final class Derived : Base, Initable {}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S4main4BaseC1xACSi_tcfC : $@convention(method) (Int, @thick Base.Type) -> @owned Base
|
||||
// CHECK: [[SELF:%.*]] = alloc_ref_dynamic %1 : $@thick Base.Type, $Base
|
||||
// CHECK: [[METHOD:%.*]] = function_ref @$S4main4BaseC1xACSi_tcfc
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]](%0, [[SELF]])
|
||||
// CHECK-NEXT: return [[RESULT]]
|
||||
// CHECK: [[METHOD:%.*]] = class_method [[SELF_META:%.*]] : $@thick Base.Type, #Base.init!allocator.1
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF_META]])
|
||||
// CHECK-NEXT: assign [[RESULT]] to [[BOX:%.*]] :
|
||||
// CHECK-NEXT: [[FINAL:%.*]] = load [copy] [[BOX]]
|
||||
// CHECK: return [[FINAL]]
|
||||
|
||||
// CHECK-LABEL: sil private [transparent] [thunk] @$S4main7DerivedCAA8InitableA2aDP1xxSi_tcfCTW : $@convention(witness_method: Initable) (Int, @thick Derived.Type) -> @out Derived
|
||||
// CHECK: [[SELF:%.*]] = upcast %2 : $@thick Derived.Type to $@thick Base.Type
|
||||
|
||||
@@ -637,18 +637,7 @@ bb0(%0 : $@thick SomeItem.Type, %1: $InitVal):
|
||||
%2 = class_method %0 : $@thick SomeItem.Type, #SomeItem.init!allocator.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
|
||||
%3 = apply %2(%1, %0) : $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
|
||||
|
||||
// CHECK-LABEL: Function call site:
|
||||
// CHECK: %4 = class_method %3 : $SomeItem, #SomeItem.init!initializer.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
|
||||
// CHECK: %5 = apply %4(%1, %3) : $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
|
||||
// CHECK-NOWMO: Incomplete callee list? : Yes
|
||||
// CHECK-WMO: Incomplete callee list? : No
|
||||
// CHECK: Known callees:
|
||||
// CHECK: SomeChildItem_initializer
|
||||
// CHECK: SomeItem_initializer
|
||||
|
||||
%4 = class_method %3 : $SomeItem, #SomeItem.init!initializer.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
|
||||
%5 = apply %4(%1, %3) : $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
|
||||
return %5 : $SomeItem
|
||||
return %3 : $SomeItem
|
||||
}
|
||||
|
||||
sil @SomeItem_allocator : $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
|
||||
|
||||
@@ -15,28 +15,28 @@ private class Base {
|
||||
private class Derived : Base {
|
||||
}
|
||||
|
||||
sil private @BaseInit : $@convention(method) (@owned Base) -> @owned Base {
|
||||
bb0(%4 : $Base):
|
||||
return %4 : $Base
|
||||
sil private @BaseInit : $@convention(method) (@thick Base.Type) -> @owned Base {
|
||||
bb0(%4 : $@thick Base.Type):
|
||||
return undef : $Base
|
||||
}
|
||||
|
||||
sil private @DerivedInit : $@convention(method) (@owned Derived) -> @owned Derived {
|
||||
bb0(%4 : $Derived):
|
||||
return %4 : $Derived
|
||||
sil private @DerivedInit : $@convention(method) (@thick Derived.Type) -> @owned Derived {
|
||||
bb0(%4 : $@thick Derived.Type):
|
||||
return undef : $Derived
|
||||
}
|
||||
|
||||
sil @testit : $@convention(method) (@owned Derived) -> @owned Derived {
|
||||
bb0(%1 : $Derived):
|
||||
%157 = class_method %1 : $Derived, #Derived.init!initializer.1 : (Derived.Type) -> () -> Derived, $@convention(method) (@owned Derived) -> @owned Derived
|
||||
return %1 : $Derived
|
||||
sil @testit : $@convention(method) (@thick Derived.Type) -> @thick Derived.Type {
|
||||
bb0(%1 : $@thick Derived.Type):
|
||||
%157 = class_method %1 : $@thick Derived.Type, #Derived.init!allocator.1 : (Derived.Type) -> () -> Derived, $@convention(method) (@thick Derived.Type) -> @owned Derived
|
||||
return %1 : $@thick Derived.Type
|
||||
}
|
||||
|
||||
sil_vtable Base {
|
||||
#Base.init!initializer.1: @BaseInit
|
||||
#Base.init!allocator.1: @BaseInit
|
||||
}
|
||||
|
||||
sil_vtable Derived {
|
||||
#Base.init!initializer.1: @DerivedInit
|
||||
#Base.init!allocator.1: @DerivedInit
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
|
||||
// RUN: -o /dev/null -Xllvm -sil-print-after=raw-sil-inst-lowering \
|
||||
// RUN: -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
|
||||
// RUN: 2>&1 | %FileCheck %s
|
||||
// REQUIRES: executable_test
|
||||
|
||||
import StdlibUnittest
|
||||
|
||||
func unwrap(_ b: Bool) throws -> Int {
|
||||
return 0
|
||||
}
|
||||
class Bear {
|
||||
let x: LifetimeTracked
|
||||
init(n: Int, before: Bool) throws {
|
||||
self.x = LifetimeTracked(0)
|
||||
}
|
||||
init(n: Int, after: Bool) throws {
|
||||
self.x = LifetimeTracked(0)
|
||||
}
|
||||
convenience init(before: Bool, before2: Bool, during: Bool, after: Bool) throws {
|
||||
try self.init(n: unwrap(before2), after: during)
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: %7 = integer_literal $Builtin.Int1, 0, loc {{.*}}:20:15, scope 1
|
||||
// CHECK-NEXT: store %7 to [trivial] %5 : $*Builtin.Int1, loc {{.*}}:20:15, scope 1
|
||||
@@ -432,18 +432,18 @@ class DelegatingCtorClass {
|
||||
}
|
||||
|
||||
convenience init(x: EmptyStruct, y: EmptyStruct) {
|
||||
_ = ivar // expected-error {{'self' used in property access 'ivar' before 'self.init' call}}
|
||||
ivar = x // expected-error {{'self' used in property access 'ivar' before 'self.init' call}}
|
||||
_ = ivar // expected-error {{'self' used before 'self.init' call}}
|
||||
ivar = x // expected-error {{'self' used before 'self.init' call}}
|
||||
self.init()
|
||||
}
|
||||
|
||||
convenience init(x: EmptyStruct, y: EmptyStruct, z: EmptyStruct) {
|
||||
self.init()
|
||||
self.init() // expected-error {{'self.init' called multiple times in initializer}}
|
||||
self.init()
|
||||
}
|
||||
|
||||
convenience init(x: (EmptyStruct, EmptyStruct)) {
|
||||
method() // expected-error {{'self' used in method call 'method' before 'self.init' call}}
|
||||
method() // expected-error {{'self' used before 'self.init' call}}
|
||||
self.init()
|
||||
}
|
||||
|
||||
@@ -1247,8 +1247,8 @@ class SuperConvenienceSub : SuperConvenienceBase {
|
||||
super.init(i)
|
||||
}
|
||||
public init(_ i1: Int, _ i2: Int, _ i3: Int) {
|
||||
self.init(i1, i1)
|
||||
}
|
||||
self.init(i1, i1) // expected-error{{'self' used before 'super.init' call}}
|
||||
} // expected-error{{'super.init' isn't called}}
|
||||
}
|
||||
|
||||
// While testing some changes I found this regression that wasn't
|
||||
|
||||
@@ -779,14 +779,11 @@ class FailableBaseClass {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfc
|
||||
// CHECK: bb0(%0 : $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfC
|
||||
// CHECK: bb0(%0 : $@thick FailableBaseClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
|
||||
// CHECK: store %0 to [[SELF_BOX]]
|
||||
// CHECK-NEXT: br bb1
|
||||
// CHECK: br bb1
|
||||
// CHECK: bb1:
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick FailableBaseClass.Type, %0 : $FailableBaseClass
|
||||
// CHECK-NEXT: dealloc_partial_ref %0 : $FailableBaseClass, [[METATYPE]] : $@thick FailableBaseClass.Type
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
|
||||
// CHECK-NEXT: br bb2
|
||||
@@ -796,10 +793,9 @@ class FailableBaseClass {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc
|
||||
// CHECK: bb0(%0 : $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfC
|
||||
// CHECK: bb0(%0 : $@thick FailableBaseClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
|
||||
// CHECK: store %0 to [[SELF_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = class_method %0
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
@@ -816,10 +812,9 @@ class FailableBaseClass {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfc
|
||||
// CHECK: bb0(%0 : $FailableBaseClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfC
|
||||
// CHECK: bb0(%0 : $@thick FailableBaseClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
|
||||
// CHECK: store %0 to [[SELF_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = class_method %0
|
||||
// CHECK-NEXT: [[SELF_OPTIONAL:%.*]] = apply [[INIT_FN]](%0)
|
||||
// CHECK: [[COND:%.*]] = select_enum [[SELF_OPTIONAL]]
|
||||
@@ -1270,14 +1265,13 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try! self.init()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
|
||||
// CHECK: bb1([[ARG:%.*]] : $Int):
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK-NEXT: strong_retain [[NEW_SELF]]
|
||||
@@ -1285,8 +1279,6 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: return [[NEW_SELF]]
|
||||
// CHECK: bb2([[ERROR:%.*]] : $Error):
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, %1 : $ThrowDerivedClass
|
||||
// CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: throw [[ERROR]]
|
||||
convenience init(failBeforeDelegation: Int) throws {
|
||||
@@ -1294,11 +1286,10 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
self.init(noFail: ())
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failDuringDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failDuringDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
|
||||
// CHECK-NEXT: try_apply [[INIT_FN]](%1)
|
||||
// CHECK: bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
@@ -1313,98 +1304,61 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try self.init()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeOrDuringDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeOrDuringDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
|
||||
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int1
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
|
||||
// CHECK: bb1([[ARG:%.*]] : $Int):
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
|
||||
// CHECK-NEXT: try_apply [[INIT_FN]](%1)
|
||||
// CHECK: bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK-NEXT: strong_retain [[NEW_SELF]]
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: return [[NEW_SELF]]
|
||||
// CHECK: bb3([[ERROR1:%.*]] : $Error):
|
||||
// CHECK-NEXT: br bb5([[ERROR1]] : $Error)
|
||||
// CHECK: bb4([[ERROR2:%.*]] : $Error):
|
||||
// CHECK-NEXT: br bb5([[ERROR2]] : $Error)
|
||||
// CHECK: bb5([[ERROR3:%.*]] : $Error):
|
||||
// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
|
||||
// CHECK: bb6:
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb7:
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, %1 : $ThrowDerivedClass
|
||||
// CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb8:
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: throw [[ERROR3]]
|
||||
convenience init(failBeforeOrDuringDelegation: Int) throws {
|
||||
try unwrap(failBeforeOrDuringDelegation)
|
||||
try self.init()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC29failBeforeOrDuringDelegation2ACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC29failBeforeOrDuringDelegation2ACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
|
||||
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int1
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
|
||||
// CHECK: bb1([[ARG:%.*]] : $Int):
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfC
|
||||
// CHECK-NEXT: try_apply [[INIT_FN]]([[ARG]], %1)
|
||||
// CHECK: bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK-NEXT: strong_retain [[NEW_SELF]]
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: return [[NEW_SELF]]
|
||||
// CHECK: bb3([[ERROR:%.*]] : $Error):
|
||||
// CHECK-NEXT: store %1 to [[SELF_BOX]]
|
||||
// CHECK-NEXT: br bb5([[ERROR]] : $Error)
|
||||
// CHECK: bb4([[ERROR1:%.*]] : $Error):
|
||||
// CHECK-NEXT: br bb5([[ERROR1]] : $Error)
|
||||
// CHECK: bb5([[ERROR2:%.*]] : $Error):
|
||||
// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
|
||||
// CHECK: bb6:
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb7:
|
||||
// CHECK-NEXT: [[RELOADED_SELF:%.*]] = load [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, [[RELOADED_SELF]] : $ThrowDerivedClass
|
||||
// CHECK-NEXT: dealloc_partial_ref [[RELOADED_SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb8:
|
||||
// CHECK: bb4([[ERROR2:%.*]] : $Error):
|
||||
// CHECK-NEXT: br bb5([[ERROR2]] : $Error)
|
||||
// CHECK: bb5([[ERROR3:%.*]] : $Error):
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: throw [[ERROR2]]
|
||||
// CHECK-NEXT: throw [[ERROR3]]
|
||||
convenience init(failBeforeOrDuringDelegation2: Int) throws {
|
||||
try self.init(failBeforeDelegation: unwrap(failBeforeOrDuringDelegation2))
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC19failAfterDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC19failAfterDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
@@ -1423,19 +1377,16 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try unwrap(failAfterDelegation)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failDuringOrAfterDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failDuringOrAfterDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
|
||||
// CHECK: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
|
||||
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
|
||||
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
|
||||
// CHECK-NEXT: try_apply [[INIT_FN]](%1)
|
||||
// CHECK: bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
@@ -1452,14 +1403,11 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
// CHECK-NEXT: br bb5([[ERROR2]] : $Error)
|
||||
// CHECK: bb5([[ERROR3:%.*]] : $Error):
|
||||
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
|
||||
// CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
|
||||
// CHECK: cond_br {{.*}}, bb7, bb6
|
||||
// CHECK: bb6:
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb7:
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb8:
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
@@ -1470,22 +1418,19 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
try unwrap(failDuringOrAfterDelegation)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failBeforeOrAfterDelegationACSi_tKcfc
|
||||
// CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass):
|
||||
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
|
||||
// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failBeforeOrAfterDelegationACSi_tKcfC
|
||||
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
|
||||
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
|
||||
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
|
||||
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
|
||||
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
|
||||
// CHECK: store %1 to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
|
||||
// CHECK: bb1([[RESULT:%.*]] : $Int):
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -2
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
|
||||
// CHECK: [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
|
||||
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
|
||||
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
|
||||
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
|
||||
@@ -1501,27 +1446,13 @@ class ThrowDerivedClass : ThrowBaseClass {
|
||||
// CHECK-NEXT: br bb5([[ERROR]] : $Error)
|
||||
// CHECK: bb5([[ERROR:%.*]] : $Error):
|
||||
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP]] : $Builtin.Int2) : $Builtin.Int1
|
||||
// CHECK-NEXT: cond_br [[COND]], bb6, bb10
|
||||
// CHECK: cond_br {{.*}}, bb7, bb6
|
||||
// CHECK: bb6:
|
||||
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
|
||||
// CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: cond_br [[COND]], bb7, bb8
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb7:
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
|
||||
// CHECK-NEXT: br bb9
|
||||
// CHECK-NEXT: br bb8
|
||||
// CHECK: bb8:
|
||||
// CHECK-NEXT: br bb9
|
||||
// CHECK: bb9:
|
||||
// CHECK-NEXT: br bb11
|
||||
// CHECK: bb10:
|
||||
// CHECK-NEXT: [[OLD_SELF:%.*]] = load [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, [[OLD_SELF]] : $ThrowDerivedClass
|
||||
// CHECK-NEXT: dealloc_partial_ref [[OLD_SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
|
||||
// CHECK-NEXT: br bb11
|
||||
// CHECK: bb11:
|
||||
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
|
||||
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
|
||||
// CHECK-NEXT: throw [[ERROR]]
|
||||
|
||||
@@ -28,7 +28,7 @@ func something(_ x: Any.Type) {}
|
||||
|
||||
// <rdar://problem/22946400> DI needs to diagnose self usages in error block
|
||||
//
|
||||
// FIXME: crappy QoI
|
||||
// FIXME: bad QoI
|
||||
class ErrantBaseClass {
|
||||
init() throws {}
|
||||
}
|
||||
@@ -87,13 +87,13 @@ class ErrantClass : ErrantBaseClass {
|
||||
do {
|
||||
try self.init()
|
||||
} catch {}
|
||||
} // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
} // expected-error {{'self.init' isn't called on all paths}}
|
||||
|
||||
convenience init(invalidEscapeConvenience2: ()) throws {
|
||||
convenience init(okEscapeConvenience2: ()) throws {
|
||||
do {
|
||||
try self.init()
|
||||
} catch {
|
||||
try self.init() // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
try self.init()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class ErrantClass : ErrantBaseClass {
|
||||
do {
|
||||
try self.init()
|
||||
} catch let e {
|
||||
print(self) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
print(self) // expected-error {{'self' used before 'self.init'}}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@@ -128,18 +128,17 @@ class ErrantClass : ErrantBaseClass {
|
||||
do {
|
||||
try self.init()
|
||||
} catch let e {
|
||||
something(x) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(self.x) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(x) // expected-error {{'self' used before 'self.init'}}
|
||||
something(self.x) // expected-error {{'self' used before 'self.init'}}
|
||||
|
||||
something(y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(self.y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(y) // expected-error {{'self' used before 'self.init'}}
|
||||
something(self.y) // expected-error {{'self' used before 'self.init'}}
|
||||
|
||||
something(&y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(&self.y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(&y) // expected-error {{'self' used before 'self.init'}}
|
||||
something(&self.y) // expected-error {{'self' used before 'self.init'}}
|
||||
|
||||
something(self) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
|
||||
something(self) // expected-error {{'self' used before 'self.init'}}
|
||||
|
||||
// FIXME: not diagnosed
|
||||
something(type(of: self))
|
||||
|
||||
throw e
|
||||
|
||||
@@ -77,75 +77,6 @@ bb0(%0 : @trivial $*MyStruct2, %1 : @trivial $@thin MyStruct2.Type):
|
||||
return %13 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil @test_delegating_box_release
|
||||
// CHECK: bb0([[ARG:%.*]] : @owned $RootClassWithNontrivialStoredProperties):
|
||||
// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
// CHECK-NEXT: [[PB:%[0-9]+]] = project_box [[SELFBOX]]
|
||||
// CHECK-NEXT: store [[ARG]] to [init] [[PB]]
|
||||
// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[PB]]
|
||||
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF]] : $RootClassWithNontrivialStoredProperties
|
||||
// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $RootClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick RootClassWithNontrivialStoredProperties.Type
|
||||
// CHECK-NEXT: dealloc_box [[SELFBOX]]
|
||||
sil @test_delegating_box_release : $@convention(method) (@owned RootClassWithNontrivialStoredProperties) -> () {
|
||||
bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
|
||||
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>, 0
|
||||
%4 = mark_uninitialized [delegatingself] %2a : $*RootClassWithNontrivialStoredProperties
|
||||
store %0 to [init] %4 : $*RootClassWithNontrivialStoredProperties
|
||||
destroy_value %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
|
||||
%13 = tuple ()
|
||||
return %13 : $()
|
||||
}
|
||||
|
||||
|
||||
// CHECK-LABEL: sil @test_delegating_rvalue_release
|
||||
// CHECK: bb0([[ARG:%.*]] : @owned $RootClassWithNontrivialStoredProperties):
|
||||
// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
// CHECK-NEXT: [[PB:%[0-9]+]] = project_box [[SELFBOX]]
|
||||
// CHECK-NEXT: store [[ARG]] to [init] [[PB]]
|
||||
// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[PB]]
|
||||
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF]] : $RootClassWithNontrivialStoredProperties
|
||||
// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $RootClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick RootClassWithNontrivialStoredProperties.Type
|
||||
// CHECK-NEXT: [[SELF2:%[0-9]+]] = load [take] [[PB]]
|
||||
// CHECK-NEXT: [[METATYPE2:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF2]] : $RootClassWithNontrivialStoredProperties
|
||||
// CHECK-NEXT: dealloc_partial_ref [[SELF2]] : $RootClassWithNontrivialStoredProperties, [[METATYPE2]] : $@thick RootClassWithNontrivialStoredProperties.Type
|
||||
// CHECK-NEXT: dealloc_box [[SELFBOX]]
|
||||
sil @test_delegating_rvalue_release : $@convention(method) (@owned RootClassWithNontrivialStoredProperties) -> () {
|
||||
bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
|
||||
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>, 0
|
||||
%4 = mark_uninitialized [delegatingself] %2a : $*RootClassWithNontrivialStoredProperties
|
||||
store %0 to [init] %4 : $*RootClassWithNontrivialStoredProperties
|
||||
%6 = load [take] %4 : $*RootClassWithNontrivialStoredProperties
|
||||
destroy_value %6 : $RootClassWithNontrivialStoredProperties
|
||||
destroy_value %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
|
||||
|
||||
%13 = tuple ()
|
||||
return %13 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil @test_delegating_derived_release
|
||||
// CHECK: bb0([[ARG:%.*]] : @owned $DerivedClassWithNontrivialStoredProperties):
|
||||
// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack $DerivedClassWithNontrivialStoredProperties
|
||||
// CHECK-NEXT: store [[ARG]] to [init] [[SELFBOX]]
|
||||
// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[SELFBOX]]
|
||||
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick DerivedClassWithNontrivialStoredProperties.Type, [[SELF]] : $DerivedClassWithNontrivialStoredProperties
|
||||
// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type
|
||||
// CHECK-NEXT: dealloc_stack [[SELFBOX]]
|
||||
sil @test_delegating_derived_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () {
|
||||
bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
|
||||
%2 = alloc_stack $DerivedClassWithNontrivialStoredProperties
|
||||
%4 = mark_uninitialized [delegatingself] %2 : $*DerivedClassWithNontrivialStoredProperties
|
||||
store %0 to [init] %4 : $*DerivedClassWithNontrivialStoredProperties
|
||||
|
||||
destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties
|
||||
dealloc_stack %2 : $*DerivedClassWithNontrivialStoredProperties
|
||||
|
||||
%13 = tuple ()
|
||||
return %13 : $()
|
||||
}
|
||||
|
||||
// <rdar://problem/20608881> DI miscompiles this testcase into a memory leak
|
||||
struct MyStruct3 {
|
||||
@sil_stored var c: C
|
||||
@@ -201,74 +132,3 @@ bb2:
|
||||
class MyClass3 {
|
||||
}
|
||||
sil @selfinit_myclass3 : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
|
||||
|
||||
// CHECK-LABEL: sil hidden @test_conditional_destroy_class_delegating_init
|
||||
sil hidden @test_conditional_destroy_class_delegating_init : $@convention(thin) (Builtin.Int1, @owned MyClass3) -> () {
|
||||
bb0(%0 : @trivial $Builtin.Int1, %1 : @owned $MyClass3):
|
||||
// CHECK: [[CONTROL:%[0-9]+]] = alloc_stack $Builtin.Int2
|
||||
// CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_stack $MyClass3
|
||||
|
||||
%2 = alloc_stack $MyClass3
|
||||
%3 = mark_uninitialized [delegatingself] %2 : $*MyClass3
|
||||
store %1 to [init] %3 : $*MyClass3
|
||||
|
||||
// CHECK: cond_br %0, [[SUCCESS:bb[0-9]+]], [[EXIT:bb[0-9]+]]
|
||||
cond_br %0, bb1, bb2
|
||||
|
||||
// CHECK: [[SUCCESS]]:
|
||||
bb1:
|
||||
%4 = load [take] %3 : $*MyClass3
|
||||
%5 = function_ref @selfinit_myclass3 : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
|
||||
%6 = apply %5(%4) : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
|
||||
store %6 to [init] %3 : $*MyClass3
|
||||
|
||||
// CHECK: [[SET:%[0-9]+]] = integer_literal $Builtin.Int2, -2
|
||||
// CHECK-NEXT: [[OLD:%.*]] = load [trivial] [[CONTROL]]
|
||||
// CHECK-NEXT: [[UPDATE:%.*]] = builtin "or_Int2"([[OLD]] : $Builtin.Int2, [[SET]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: store [[UPDATE]] to [trivial] [[CONTROL]] : $*Builtin.Int2
|
||||
|
||||
// CHECK: [[SET:%[0-9]+]] = integer_literal $Builtin.Int2, 1
|
||||
// CHECK-NEXT: [[OLD:%.*]] = load [trivial] [[CONTROL]]
|
||||
// CHECK-NEXT: [[UPDATE:%.*]] = builtin "or_Int2"([[OLD]] : $Builtin.Int2, [[SET]] : $Builtin.Int2)
|
||||
// CHECK-NEXT: store [[UPDATE]] to [trivial] [[CONTROL]] : $*Builtin.Int2
|
||||
|
||||
// CHECK: [[NEW_SELF:%[0-9]+]] = apply {{.*}}({{.*}}) : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [init] [[SELF_BOX]] : $*MyClass3
|
||||
|
||||
// CHECK-NEXT: br [[CHECK:bb[0-9]+]]
|
||||
br bb2
|
||||
|
||||
// CHECK: [[CHECK]]:
|
||||
bb2:
|
||||
|
||||
// CHECK-NEXT: [[BIT:%.*]] = load [trivial] [[CONTROL]]
|
||||
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BIT]] : $Builtin.Int2) : $Builtin.Int1
|
||||
// CHECK-NEXT: cond_br [[COND]], [[PARTIAL:bb[0-9]+]], [[UNINITIALIZED:bb[0-9]+]]
|
||||
|
||||
// CHECK: [[PARTIAL]]:
|
||||
// CHECK-NEXT: [[BIT:%.*]] = load [trivial] [[CONTROL]]
|
||||
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
|
||||
// CHECK-NEXT: [[SHIFTED:%.*]] = builtin "lshr_Int2"([[BIT]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
|
||||
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[SHIFTED]] : $Builtin.Int2) : $Builtin.Int1
|
||||
// CHECK-NEXT: cond_br [[COND]], [[INITIALIZED:bb[0-9]+]], [[CONSUMED:bb[0-9]+]]
|
||||
|
||||
// CHECK: [[INITIALIZED]]:
|
||||
// CHECK-NEXT: destroy_addr [[SELF_BOX]] : $*MyClass3
|
||||
// CHECK-NEXT: br [[EXIT:bb[0-9]+]]
|
||||
|
||||
// CHECK: [[CONSUMED]]:
|
||||
// CHECK-NEXT: br [[EXIT]]
|
||||
|
||||
// CHECK: [[UNINITIALIZED]]:
|
||||
// CHECK-NEXT: [[OLD_SELF:%[0-9]+]] = load [take] [[SELF_BOX]] : $*MyClass3
|
||||
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick MyClass3.Type, [[OLD_SELF]] : $MyClass3
|
||||
// CHECK-NEXT: dealloc_partial_ref [[OLD_SELF]] : $MyClass3, [[METATYPE]] : $@thick MyClass3.Type
|
||||
// CHECK-NEXT: br [[EXIT:bb[0-9]+]]
|
||||
|
||||
// CHECK: [[EXIT]]:
|
||||
|
||||
destroy_addr %3 : $*MyClass3
|
||||
dealloc_stack %2 : $*MyClass3
|
||||
%7 = tuple ()
|
||||
return %7 : $()
|
||||
}
|
||||
|
||||
@@ -17,21 +17,14 @@ func testInstanceTypeFactoryMethod(queen: Bee) {
|
||||
}
|
||||
|
||||
extension Hive {
|
||||
// FIXME: This whole approach is wrong. This should be a factory
|
||||
// initializer, not a convenience initializer, which means it does
|
||||
// not have an initializing entry point at all.
|
||||
|
||||
// CHECK-LABEL: sil hidden @$SSo4HiveC027definite_init_objc_factory_C0E10otherQueenABSo3BeeC_tcfc : $@convention(method) (@owned Bee, @owned Hive) -> @owned Hive
|
||||
// CHECK-LABEL: sil hidden @$SSo4HiveC027definite_init_objc_factory_C0E10otherQueenABSo3BeeC_tcfC
|
||||
convenience init(otherQueen other: Bee) {
|
||||
// CHECK: bb0({{.*}}, [[META:%.*]] : $@thick Hive.Type)
|
||||
// CHECK: [[SELF_ADDR:%[0-9]+]] = alloc_stack $Hive
|
||||
// CHECK: store [[OLD_SELF:%[0-9]+]] to [[SELF_ADDR]]
|
||||
// CHECK: [[META:%[0-9]+]] = value_metatype $@thick Hive.Type, [[OLD_SELF]] : $Hive
|
||||
// CHECK: [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]] : $@thick Hive.Type to $@objc_metatype Hive.Type
|
||||
// CHECK: [[FACTORY:%[0-9]+]] = objc_method [[OBJC_META]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (Bee?) -> Hive?, $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
|
||||
// CHECK: apply [[FACTORY]]([[QUEEN:%[0-9]+]], [[OBJC_META]]) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
|
||||
// CHECK: store [[NEW_SELF:%[0-9]+]] to [[SELF_ADDR]]
|
||||
// CHECK: [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[OLD_SELF]] : $Hive
|
||||
// CHECK: dealloc_partial_ref [[OLD_SELF]] : $Hive, [[METATYPE]] : $@thick Hive.Type
|
||||
// CHECK: dealloc_stack [[SELF_ADDR]]
|
||||
// CHECK: return [[NEW_SELF]]
|
||||
self.init(queen: other)
|
||||
@@ -54,17 +47,14 @@ extension SomeClass {
|
||||
}
|
||||
|
||||
class SubHive : Hive {
|
||||
// CHECK-LABEL: sil hidden @$S027definite_init_objc_factory_B07SubHiveC20delegatesToInheritedACyt_tcfc : $@convention(method) (@owned SubHive) -> @owned SubHive
|
||||
// CHECK-LABEL: sil hidden @$S027definite_init_objc_factory_B07SubHiveC20delegatesToInheritedACyt_tcfC
|
||||
convenience init(delegatesToInherited: ()) {
|
||||
// CHECK: [[UPCAST:%.*]] = upcast %0 : $SubHive to $Hive
|
||||
// CHECK: [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[UPCAST]] : $Hive
|
||||
// CHECK: [[OBJC:%.*]] = thick_to_objc_metatype [[METATYPE]] : $@thick Hive.Type to $@objc_metatype Hive.Type
|
||||
// CHECK: bb0([[METATYPE:%.*]] : $@thick SubHive.Type)
|
||||
// CHECK: [[UPMETA:%.*]] = upcast [[METATYPE]]
|
||||
// CHECK: [[OBJC:%.*]] = thick_to_objc_metatype [[UPMETA]] : $@thick Hive.Type to $@objc_metatype Hive.Type
|
||||
// CHECK: [[METHOD:%.*]] = objc_method [[OBJC]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (Bee?) -> Hive?
|
||||
// CHECK: apply [[METHOD]]({{.*}}, [[OBJC]])
|
||||
|
||||
// CHECK: [[METATYPE:%.*]] = value_metatype $@thick SubHive.Type, %0 : $SubHive
|
||||
// CHECK-NEXT: dealloc_partial_ref %0 : $SubHive, [[METATYPE]] : $@thick SubHive.Type
|
||||
|
||||
// CHECK: return {{%.*}} : $SubHive
|
||||
self.init(queen: Bee())
|
||||
}
|
||||
|
||||
@@ -25,20 +25,17 @@ extension TriviallyConstructible {
|
||||
class TrivialClass : TriviallyConstructible {
|
||||
required init(lower: Int) {}
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S023definite_init_protocol_B012TrivialClassC5upperACSi_tcfc
|
||||
// CHECK: bb0(%0 : $Int, [[OLD_SELF:%.*]] : $TrivialClass):
|
||||
// CHECK-LABEL: sil hidden @$S023definite_init_protocol_B012TrivialClassC5upperACSi_tcfC
|
||||
// CHECK: bb0(%0 : $Int, [[SELF_META:%.*]] : $@thick TrivialClass.Type):
|
||||
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $TrivialClass
|
||||
// CHECK-NEXT: debug_value
|
||||
// CHECK-NEXT: store [[OLD_SELF]] to [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick @dynamic_self TrivialClass.Type, %1
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = unchecked_trivial_bit_cast [[SELF_META]] {{.*}} to $@thick @dynamic_self TrivialClass.Type
|
||||
// CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $TrivialClass
|
||||
// CHECK-NEXT: // function_ref
|
||||
// CHECK-NEXT: [[FN:%.*]] = function_ref @$S023definite_init_protocol_B022TriviallyConstructiblePAAE6middlexSi_tcfC
|
||||
// CHECK-NEXT: apply [[FN]]<@dynamic_self TrivialClass>([[RESULT]], %0, [[METATYPE]])
|
||||
// CHECK-NEXT: [[NEW_SELF:%.*]] = load [[RESULT]]
|
||||
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
|
||||
// CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick TrivialClass.Type, %1
|
||||
// CHECK-NEXT: dealloc_partial_ref %1 : $TrivialClass, [[METATYPE]] : $@thick TrivialClass.Type
|
||||
// CHECK-NEXT: dealloc_stack [[RESULT]]
|
||||
// TODO: Once we restore arbitrary takes, the strong_retain/destroy_addr pair below will go away.
|
||||
// CHECK-NEXT: strong_retain [[NEW_SELF]]
|
||||
|
||||
@@ -109,9 +109,9 @@ public class Bear {
|
||||
|
||||
// Check that devirtualizer can handle convenience initializers, which have covariant optional
|
||||
// return types.
|
||||
// CHECK-LABEL: sil @$S23devirt_covariant_return4BearC{{[_0-9a-zA-Z]*}}fc
|
||||
// CHECK: checked_cast_br [exact] %{{.*}} : $Bear to $PolarBear
|
||||
// CHECK: upcast %{{.*}} : $Optional<PolarBear> to $Optional<Bear>
|
||||
// CHECK-LABEL: sil @$S23devirt_covariant_return4BearC{{[_0-9a-zA-Z]*}}fC
|
||||
// CHECK: checked_cast_br [exact] %{{.*}} : $@thick Bear.Type to $@thick GummyBear.Type
|
||||
// CHECK: upcast %{{.*}} : $Optional<GummyBear> to $Optional<Bear>
|
||||
// CHECK: }
|
||||
public convenience init?(delegateFailure: Bool, failAfter: Bool) {
|
||||
self.init(fail: delegateFailure)
|
||||
@@ -119,7 +119,7 @@ public class Bear {
|
||||
}
|
||||
}
|
||||
|
||||
final class PolarBear: Bear {
|
||||
final class GummyBear: Bear {
|
||||
|
||||
override init?(fail: Bool) {
|
||||
super.init(fail: fail)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// the constructor itself is not "open".
|
||||
|
||||
open class OpenClass {
|
||||
// CHECK-LABEL: sil @$S4test9OpenClassC1xACSi_tcfc : $@convention(method) (Int, @owned OpenClass) -> @owned OpenClass
|
||||
// CHECK: [[M:%[0-9]+]] = class_method %1 : $OpenClass, #OpenClass.init!initializer.1 : (OpenClass.Type) -> (Int, Int) -> OpenClass
|
||||
// CHECK-LABEL: sil @$S4test9OpenClassC1xACSi_tcfC
|
||||
// CHECK: [[M:%[0-9]+]] = class_method %1 : $@thick OpenClass.Type, #OpenClass.init!allocator.1
|
||||
// CHECK: apply [[M]]
|
||||
// CHECK: return
|
||||
public convenience init(x: Int) {
|
||||
@@ -19,8 +19,8 @@ open class OpenClass {
|
||||
// Static dispatch for not-open class (we are compiling with -wmo).
|
||||
|
||||
public class PublicClass {
|
||||
// CHECK-LABEL: sil @$S4test11PublicClassC1xACSi_tcfc : $@convention(method) (Int, @owned PublicClass) -> @owned PublicClass
|
||||
// CHECK: [[M:%[0-9]+]] = function_ref @$S4test11PublicClassC1x1yACSi_Sitcfc : $@convention(method) (Int, Int, @owned PublicClass) -> @owned PublicClass
|
||||
// CHECK-LABEL: sil @$S4test11PublicClassC1xACSi_tcfC
|
||||
// CHECK: [[M:%[0-9]+]] = function_ref @$S4test11PublicClassC1x1yACSi_SitcfC
|
||||
// CHECK: apply [[M]]
|
||||
// CHECK: return
|
||||
public convenience init(x: Int) {
|
||||
|
||||
@@ -35,7 +35,7 @@ public func testVTableBuilding(user: User) {
|
||||
// for the vtable slot for 'lastMethod()'. If the layout here
|
||||
// changes, please check that offset is still correct.
|
||||
// CHECK-IR-NOT: ret
|
||||
// CHECK-IR: getelementptr inbounds void (%T3Lib4UserC*)*, void (%T3Lib4UserC*)** %{{[0-9]+}}, {{i64 30|i32 33}}
|
||||
// CHECK-IR: getelementptr inbounds void (%T3Lib4UserC*)*, void (%T3Lib4UserC*)** %{{[0-9]+}}, {{i64 26|i32 29}}
|
||||
_ = user.lastMethod()
|
||||
} // CHECK-IR: ret void
|
||||
|
||||
@@ -180,15 +180,11 @@ open class User {
|
||||
// 19 CHECK-VTABLE-NEXT: #User.constrainedWrapped!1:
|
||||
// 20 CHECK-VTABLE-NEXT: #User.subscript!getter.1:
|
||||
// 21 CHECK-VTABLE-NEXT: #User.subscript!getter.1:
|
||||
// 22 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 23 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 24 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 25 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 26 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 27 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 28 CHECK-VTABLE-NEXT: #User.init!initializer.1:
|
||||
// 29 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 30 CHECK-VTABLE-NEXT: #User.lastMethod!1:
|
||||
// 22 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 23 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 24 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 25 CHECK-VTABLE-NEXT: #User.init!allocator.1:
|
||||
// 26 CHECK-VTABLE-NEXT: #User.lastMethod!1:
|
||||
// CHECK-VTABLE: }
|
||||
|
||||
|
||||
|
||||
@@ -13,13 +13,11 @@ func sr8083(decoder: Decoder) throws {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil_vtable SR8083_Base {
|
||||
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfc // SR8083_Base.init()
|
||||
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfC
|
||||
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfC
|
||||
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfc // SR8083_Base.init(from:)
|
||||
// CHECK: {{^}$}}
|
||||
|
||||
// CHECK-LABEL: sil_vtable SR8083_Sub {
|
||||
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfc [override] // SR8083_Sub.init()
|
||||
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfC [override]
|
||||
// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfC [override] // SR8083_Sub.__allocating_init(from:)
|
||||
// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfc [override] // SR8083_Sub.init(from:)
|
||||
// CHECK: {{^}$}}
|
||||
|
||||
Reference in New Issue
Block a user