mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Revert "SIL: Drop the upcast_existential* instructions."
This reverts commit r22345. Swift SVN r22353
This commit is contained in:
34
docs/SIL.rst
34
docs/SIL.rst
@@ -2909,6 +2909,26 @@ initialized existential container can be destroyed with ``destroy_addr`` as
|
||||
usual. It is undefined behavior to ``destroy_addr`` a partially-initialized
|
||||
existential container.
|
||||
|
||||
upcast_existential
|
||||
``````````````````
|
||||
::
|
||||
|
||||
sil-instruction ::= 'upcast_existential' '[take]'? sil-operand
|
||||
'to' sil-operand
|
||||
|
||||
upcast_existential %0 : $*protocol<P, Q> to %1 : $*P
|
||||
// %0 must be the address of a non-class protocol or protocol composition
|
||||
// type
|
||||
// %1 must be the address of a non-class protocol or protocol composition
|
||||
// type that is a supertype of %0
|
||||
|
||||
Initializes the memory referenced by the destination ``%1`` with the value
|
||||
contained in the existing existential container referenced by ``%0``.
|
||||
The ``[take]`` attribute may be applied to the instruction, in which case,
|
||||
the source existential container is destroyed and ownership of the contained
|
||||
value is taken by the destination. Without the ``[take]`` attribute, the
|
||||
destination receives an independently-owned copy of the value.
|
||||
|
||||
deinit_existential
|
||||
``````````````````
|
||||
::
|
||||
@@ -2998,6 +3018,20 @@ init_existential_ref
|
||||
Creates a class existential container of type ``$P`` containing a reference to
|
||||
the class instance ``%0``.
|
||||
|
||||
upcast_existential_ref
|
||||
``````````````````````
|
||||
::
|
||||
|
||||
sil-instruction ::= 'upcast_existential_ref' sil-operand 'to' sil-type
|
||||
|
||||
%1 = upcast_existential_ref %0 : $protocol<P, Q> to $P
|
||||
// %0 must be of a class protocol or protocol composition type
|
||||
// $P must be a class protocol or protocol composition type that is a
|
||||
// supertype of %0's type
|
||||
|
||||
Converts a class existential container to a more general protocol or protocol
|
||||
composition type.
|
||||
|
||||
project_existential_ref
|
||||
```````````````````````
|
||||
::
|
||||
|
||||
@@ -370,6 +370,7 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialRefInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(InitExistentialInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(InitExistentialRefInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(DeinitExistentialInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(UpcastExistentialRefInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(ProjectBlockStorageInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongRetainInst)
|
||||
UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongReleaseInst)
|
||||
|
||||
@@ -661,6 +661,22 @@ public:
|
||||
Conformances, &F));
|
||||
}
|
||||
|
||||
UpcastExistentialInst *createUpcastExistential(SILLocation Loc,
|
||||
SILValue SrcExistential,
|
||||
SILValue DestExistential,
|
||||
IsTake_t isTakeOfSrc) {
|
||||
return insert(new (F.getModule())
|
||||
UpcastExistentialInst(Loc, SrcExistential, DestExistential,
|
||||
isTakeOfSrc));
|
||||
}
|
||||
|
||||
UpcastExistentialRefInst *createUpcastExistentialRef(SILLocation Loc,
|
||||
SILValue Operand,
|
||||
SILType Ty) {
|
||||
return insert(new (F.getModule())
|
||||
UpcastExistentialRefInst(Loc, Operand, Ty));
|
||||
}
|
||||
|
||||
DeinitExistentialInst *createDeinitExistential(SILLocation Loc,
|
||||
SILValue Existential) {
|
||||
return insert(new (F.getModule()) DeinitExistentialInst(Loc, Existential));
|
||||
|
||||
@@ -1027,6 +1027,26 @@ SILCloner<ImplClass>::visitDeinitExistentialInst(DeinitExistentialInst *Inst) {
|
||||
getOpValue(Inst->getOperand())));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitUpcastExistentialInst(UpcastExistentialInst *Inst) {
|
||||
doPostProcess(Inst,
|
||||
getBuilder().createUpcastExistential(getOpLocation(Inst->getLoc()),
|
||||
getOpValue(Inst->getSrcExistential()),
|
||||
getOpValue(Inst->getDestExistential()),
|
||||
(IsTake_t)Inst->isTakeOfSrc()));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::
|
||||
visitUpcastExistentialRefInst(UpcastExistentialRefInst *Inst) {
|
||||
doPostProcess(Inst,
|
||||
getBuilder().createUpcastExistentialRef(getOpLocation(Inst->getLoc()),
|
||||
getOpValue(Inst->getOperand()),
|
||||
getOpType(Inst->getType())));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitCopyBlockInst(CopyBlockInst *Inst) {
|
||||
|
||||
@@ -2139,6 +2139,50 @@ public:
|
||||
: UnaryInstructionBase(Loc, Existential) {}
|
||||
};
|
||||
|
||||
/// UpcastExistentialInst - Copies the concrete value from an existential
|
||||
/// container of a protocol type to another uninitialized existential container
|
||||
/// for a supertype of the original protocol type. The destination can be
|
||||
/// of a base protocol type or of a protocol composition that is a superset
|
||||
/// of the original type (or a protocol composition of base protocols).
|
||||
class UpcastExistentialInst : public SILInstruction {
|
||||
unsigned IsTakeOfSrc : 1;
|
||||
enum { SrcExistential, DestExistential };
|
||||
FixedOperandList<2> Operands;
|
||||
public:
|
||||
UpcastExistentialInst(SILLocation Loc,
|
||||
SILValue SrcExistential,
|
||||
SILValue DestExistential,
|
||||
IsTake_t isTakeOfSrc);
|
||||
|
||||
SILValue getSrcExistential() const { return Operands[SrcExistential].get(); }
|
||||
SILValue getDestExistential() const { return Operands[DestExistential].get();}
|
||||
|
||||
/// True if the destination can take ownership of the concrete value from the
|
||||
/// source.
|
||||
IsTake_t isTakeOfSrc() const { return IsTake_t(IsTakeOfSrc); }
|
||||
|
||||
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
|
||||
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
|
||||
|
||||
static bool classof(const ValueBase *V) {
|
||||
return V->getKind() == ValueKind::UpcastExistentialInst;
|
||||
}
|
||||
};
|
||||
|
||||
/// UpcastExistentialRefInst - Converts a value of class existential
|
||||
/// container to another, more general class existential container type.
|
||||
class UpcastExistentialRefInst
|
||||
: public UnaryInstructionBase<ValueKind::UpcastExistentialRefInst,
|
||||
ConversionInst>
|
||||
{
|
||||
public:
|
||||
UpcastExistentialRefInst(SILLocation Loc,
|
||||
SILValue Operand,
|
||||
SILType DestTy)
|
||||
: UnaryInstructionBase(Loc, Operand, DestTy)
|
||||
{}
|
||||
};
|
||||
|
||||
/// Projects the capture storage address from a @block_storage address.
|
||||
class ProjectBlockStorageInst
|
||||
: public UnaryInstructionBase<ValueKind::ProjectBlockStorageInst,
|
||||
|
||||
@@ -159,10 +159,12 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
|
||||
|
||||
// Protocol and Protocol Composition Types
|
||||
INST(InitExistentialInst, SILInstruction, MayWrite)
|
||||
INST(UpcastExistentialInst, SILInstruction, MayWrite)
|
||||
INST(DeinitExistentialInst, SILInstruction, MayHaveSideEffects)
|
||||
INST(ProjectExistentialInst, SILInstruction, None)
|
||||
INST(OpenExistentialInst, SILInstruction, None)
|
||||
INST(InitExistentialRefInst, SILInstruction, None)
|
||||
INST(UpcastExistentialRefInst, SILInstruction, None)
|
||||
INST(ProjectExistentialRefInst, SILInstruction, None)
|
||||
INST(OpenExistentialRefInst, SILInstruction, None)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// Serialized module format minor version number.
|
||||
///
|
||||
/// When the format changes IN ANY WAY, this number should be incremented.
|
||||
const uint16_t VERSION_MINOR = 148;
|
||||
const uint16_t VERSION_MINOR = 147;
|
||||
|
||||
using DeclID = Fixnum<31>;
|
||||
using DeclIDField = BCFixed<31>;
|
||||
|
||||
@@ -646,6 +646,8 @@ public:
|
||||
void visitOpenExistentialRefInst(OpenExistentialRefInst *i);
|
||||
void visitInitExistentialInst(InitExistentialInst *i);
|
||||
void visitInitExistentialRefInst(InitExistentialRefInst *i);
|
||||
void visitUpcastExistentialInst(UpcastExistentialInst *i);
|
||||
void visitUpcastExistentialRefInst(UpcastExistentialRefInst *i);
|
||||
void visitDeinitExistentialInst(DeinitExistentialInst *i);
|
||||
|
||||
void visitProjectBlockStorageInst(ProjectBlockStorageInst *i);
|
||||
@@ -3176,6 +3178,30 @@ void IRGenSILFunction::visitInitExistentialRefInst(InitExistentialRefInst *i) {
|
||||
setLoweredExplosion(SILValue(i, 0), result);
|
||||
}
|
||||
|
||||
void IRGenSILFunction::visitUpcastExistentialInst(
|
||||
swift::UpcastExistentialInst *i) {
|
||||
/// FIXME: Handle source existential being class existential.
|
||||
Address src = getLoweredAddress(i->getSrcExistential());
|
||||
Address dest = getLoweredAddress(i->getDestExistential());
|
||||
SILType srcType = i->getSrcExistential().getType();
|
||||
SILType destType = i->getDestExistential().getType();
|
||||
emitOpaqueExistentialContainerUpcast(*this, dest, destType, src, srcType,
|
||||
i->isTakeOfSrc());
|
||||
}
|
||||
|
||||
void IRGenSILFunction::visitUpcastExistentialRefInst(
|
||||
swift::UpcastExistentialRefInst *i) {
|
||||
Explosion src = getLoweredExplosion(i->getOperand());
|
||||
Explosion dest;
|
||||
SILType srcType = i->getOperand().getType();
|
||||
SILType destType = i->getType();
|
||||
|
||||
emitClassExistentialContainerUpcast(*this, dest, destType,
|
||||
src, srcType);
|
||||
|
||||
setLoweredExplosion(SILValue(i, 0), dest);
|
||||
}
|
||||
|
||||
void IRGenSILFunction::visitDeinitExistentialInst(
|
||||
swift::DeinitExistentialInst *i) {
|
||||
Address container = getLoweredAddress(i->getOperand());
|
||||
|
||||
@@ -1238,6 +1238,8 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc,
|
||||
.Case("unowned_to_ref", ValueKind::UnownedToRefInst)
|
||||
.Case("unreachable", ValueKind::UnreachableInst)
|
||||
.Case("upcast", ValueKind::UpcastInst)
|
||||
.Case("upcast_existential", ValueKind::UpcastExistentialInst)
|
||||
.Case("upcast_existential_ref", ValueKind::UpcastExistentialRefInst)
|
||||
.Default(ValueKind::SILArgument);
|
||||
|
||||
if (Opcode != ValueKind::SILArgument) {
|
||||
@@ -1702,6 +1704,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
case ValueKind::ThickToObjCMetatypeInst:
|
||||
case ValueKind::ObjCToThickMetatypeInst:
|
||||
case ValueKind::ConvertFunctionInst:
|
||||
case ValueKind::UpcastExistentialRefInst:
|
||||
case ValueKind::ObjCExistentialMetatypeToObjectInst:
|
||||
case ValueKind::ObjCMetatypeToObjectInst: {
|
||||
SILType Ty;
|
||||
@@ -1771,6 +1774,9 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
case ValueKind::ObjCToThickMetatypeInst:
|
||||
ResultVal = B.createObjCToThickMetatype(InstLoc, Val, Ty);
|
||||
break;
|
||||
case ValueKind::UpcastExistentialRefInst:
|
||||
ResultVal = B.createUpcastExistentialRef(InstLoc, Val, Ty);
|
||||
break;
|
||||
case ValueKind::ObjCMetatypeToObjectInst:
|
||||
ResultVal = B.createObjCMetatypeToObject(InstLoc, Val, Ty);
|
||||
break;
|
||||
@@ -2444,6 +2450,26 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
IsInitialization_t(IsInit));
|
||||
break;
|
||||
}
|
||||
case ValueKind::UpcastExistentialInst: {
|
||||
SILValue DestVal;
|
||||
SourceLoc SrcLoc, DestLoc, ToLoc;
|
||||
Identifier ToToken;
|
||||
bool IsTake = false;
|
||||
if (parseSILOptional(IsTake, *this, "take") ||
|
||||
parseTypedValueRef(Val, SrcLoc) ||
|
||||
parseSILIdentifier(ToToken, ToLoc,
|
||||
diag::expected_tok_in_sil_instr, "to") ||
|
||||
parseTypedValueRef(DestVal, DestLoc))
|
||||
return true;
|
||||
|
||||
if (ToToken.str() != "to") {
|
||||
P.diagnose(ToLoc, diag::expected_tok_in_sil_instr, "to");
|
||||
return true;
|
||||
}
|
||||
ResultVal = B.createUpcastExistential(InstLoc, Val, DestVal,
|
||||
IsTake_t(IsTake));
|
||||
break;
|
||||
}
|
||||
case ValueKind::StructInst: {
|
||||
SILType StructTy;
|
||||
if (parseSILType(StructTy) ||
|
||||
|
||||
@@ -472,6 +472,10 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool visitUpcastExistentialRefInst(UpcastExistentialRefInst *RHS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool visitObjCMetatypeToObjectInst(ObjCMetatypeToObjectInst *RHS) {
|
||||
return true;
|
||||
}
|
||||
@@ -1024,6 +1028,17 @@ OpenExistentialRefInst::OpenExistentialRefInst(SILLocation Loc,
|
||||
: UnaryInstructionBase(Loc, Operand, Ty)
|
||||
{}
|
||||
|
||||
UpcastExistentialInst::UpcastExistentialInst(SILLocation Loc,
|
||||
SILValue SrcExistential,
|
||||
SILValue DestExistential,
|
||||
IsTake_t isTakeOfSrc)
|
||||
: SILInstruction(ValueKind::UpcastExistentialInst, Loc),
|
||||
IsTakeOfSrc(isTakeOfSrc),
|
||||
Operands(this, SrcExistential, DestExistential)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions representing terminators
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -850,6 +850,9 @@ public:
|
||||
void visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *CI) {
|
||||
printUncheckedConversionInst(CI, CI->getOperand(),"objc_to_thick_metatype");
|
||||
}
|
||||
void visitUpcastExistentialRefInst(UpcastExistentialRefInst *CI) {
|
||||
printUncheckedConversionInst(CI, CI->getOperand(),"upcast_existential_ref");
|
||||
}
|
||||
void visitObjCMetatypeToObjectInst(ObjCMetatypeToObjectInst *CI) {
|
||||
printUncheckedConversionInst(CI, CI->getOperand(),
|
||||
"objc_metatype_to_object");
|
||||
@@ -1044,6 +1047,13 @@ public:
|
||||
<< " : $" << AEI->getFormalConcreteType()
|
||||
<< ", " << AEI->getType();
|
||||
}
|
||||
void visitUpcastExistentialInst(UpcastExistentialInst *UEI) {
|
||||
OS << "upcast_existential ";
|
||||
if (UEI->isTakeOfSrc())
|
||||
OS << "[take] ";
|
||||
OS << getIDAndType(UEI->getSrcExistential())
|
||||
<< " to " << getIDAndType(UEI->getDestExistential());
|
||||
}
|
||||
void visitDeinitExistentialInst(DeinitExistentialInst *DEI) {
|
||||
OS << "deinit_existential " << getIDAndType(DEI->getOperand());
|
||||
}
|
||||
|
||||
@@ -1500,6 +1500,34 @@ public:
|
||||
"Could not find witness table for conformance.");
|
||||
}
|
||||
|
||||
void checkUpcastExistentialInst(UpcastExistentialInst *UEI) {
|
||||
SILType srcType = UEI->getSrcExistential().getType();
|
||||
SILType destType = UEI->getDestExistential().getType();
|
||||
require(srcType != destType,
|
||||
"can't upcast_existential to same type");
|
||||
require(srcType.isExistentialType(),
|
||||
"upcast_existential source must be existential");
|
||||
require(destType.isAddress(),
|
||||
"upcast_existential dest must be an address");
|
||||
require(destType.isExistentialType(),
|
||||
"upcast_existential dest must be address of existential");
|
||||
require(!destType.isClassExistentialType(),
|
||||
"upcast_existential dest must be non-class existential");
|
||||
}
|
||||
|
||||
void checkUpcastExistentialRefInst(UpcastExistentialRefInst *UEI) {
|
||||
require(UEI->getOperand().getType() != UEI->getType(),
|
||||
"can't upcast_existential_ref to same type");
|
||||
require(UEI->getOperand().getType().isObject(),
|
||||
"upcast_existential_ref operand must not be an address");
|
||||
require(UEI->getOperand().getType().isClassExistentialType(),
|
||||
"upcast_existential_ref operand must be class existential");
|
||||
require(UEI->getType().isObject(),
|
||||
"upcast_existential_ref result must not be an address");
|
||||
require(UEI->getType().isClassExistentialType(),
|
||||
"upcast_existential_ref result must be class existential");
|
||||
}
|
||||
|
||||
void checkDeinitExistentialInst(DeinitExistentialInst *DEI) {
|
||||
SILType exType = DEI->getOperand().getType();
|
||||
require(exType.isAddress(),
|
||||
|
||||
@@ -636,6 +636,7 @@ public:
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(InjectEnumAddrInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(UncheckedTakeEnumDataAddrInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(InitExistentialInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(UpcastExistentialInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(DeinitExistentialInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(DeallocStackInst)
|
||||
OPERANDALIAS_MEMBEHAVIOR_INST(FixLifetimeInst)
|
||||
|
||||
@@ -94,6 +94,7 @@ static bool isTransitiveEscapeInst(SILInstruction *Inst) {
|
||||
case ValueKind::DynamicMethodBranchInst:
|
||||
case ValueKind::ReturnInst:
|
||||
case ValueKind::AutoreleaseReturnInst:
|
||||
case ValueKind::UpcastExistentialInst:
|
||||
case ValueKind::FixLifetimeInst:
|
||||
return false;
|
||||
|
||||
@@ -153,6 +154,7 @@ static bool isTransitiveEscapeInst(SILInstruction *Inst) {
|
||||
case ValueKind::UnconditionalCheckedCastAddrInst:
|
||||
case ValueKind::UnmanagedToRefInst:
|
||||
case ValueKind::UnownedToRefInst:
|
||||
case ValueKind::UpcastExistentialRefInst:
|
||||
case ValueKind::UpcastInst:
|
||||
return true;
|
||||
|
||||
|
||||
@@ -666,6 +666,15 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// upcast_existential is modeled as a load or initialization depending on
|
||||
// which operand we're looking at.
|
||||
if (isa<UpcastExistentialInst>(User)) {
|
||||
auto Kind = UI->getOperandNumber() == 1 ?
|
||||
DIUseKind::Initialization : DIUseKind::Load;
|
||||
Uses.push_back(DIMemoryUse(User, Kind, BaseEltNo, 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// project_existential and open_existential are uses of the protocol value,
|
||||
// so it is modeled as a load.
|
||||
if (isa<ProjectExistentialInst>(User) || isa<ProtocolMethodInst>(User)
|
||||
|
||||
@@ -256,6 +256,7 @@ static InlineCost instructionInlineCost(SILInstruction &I,
|
||||
case ValueKind::RawPointerToRefInst:
|
||||
case ValueKind::RefToRawPointerInst:
|
||||
|
||||
case ValueKind::UpcastExistentialRefInst:
|
||||
case ValueKind::UpcastInst:
|
||||
|
||||
case ValueKind::ThinToThickFunctionInst:
|
||||
@@ -364,6 +365,7 @@ static InlineCost instructionInlineCost(SILInstruction &I,
|
||||
case ValueKind::UnownedReleaseInst:
|
||||
case ValueKind::UnownedRetainInst:
|
||||
case ValueKind::UnownedToRefInst:
|
||||
case ValueKind::UpcastExistentialInst:
|
||||
case ValueKind::InitBlockStorageHeaderInst:
|
||||
return InlineCost::Expensive;
|
||||
|
||||
|
||||
@@ -755,6 +755,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
ONEOPERAND_ONETYPE_INST(ObjCMetatypeToObject)
|
||||
ONEOPERAND_ONETYPE_INST(ObjCExistentialMetatypeToObject)
|
||||
ONEOPERAND_ONETYPE_INST(ConvertFunction)
|
||||
ONEOPERAND_ONETYPE_INST(UpcastExistentialRef)
|
||||
ONEOPERAND_ONETYPE_INST(ProjectBlockStorage)
|
||||
#undef ONEOPERAND_ONETYPE_INST
|
||||
|
||||
@@ -971,6 +972,18 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
getSILType(Ty2, (SILValueCategory)TyCategory2)));
|
||||
break;
|
||||
}
|
||||
case ValueKind::UpcastExistentialInst: {
|
||||
auto Ty = MF->getType(TyID);
|
||||
auto Ty2 = MF->getType(TyID2);
|
||||
bool isTake = (Attr > 0);
|
||||
ResultVal = Builder.createUpcastExistential(Loc,
|
||||
getLocalValue(ValID, ValResNum,
|
||||
getSILType(Ty, (SILValueCategory)TyCategory)),
|
||||
getLocalValue(ValID2, ValResNum2,
|
||||
getSILType(Ty2, (SILValueCategory)TyCategory2)),
|
||||
IsTake_t(isTake));
|
||||
break;
|
||||
}
|
||||
case ValueKind::IntegerLiteralInst: {
|
||||
auto Ty = MF->getType(TyID);
|
||||
auto intTy = Ty->getAs<BuiltinIntegerType>();
|
||||
|
||||
@@ -713,13 +713,18 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
||||
break;
|
||||
}
|
||||
case ValueKind::IndexAddrInst:
|
||||
case ValueKind::IndexRawPointerInst: {
|
||||
case ValueKind::IndexRawPointerInst:
|
||||
case ValueKind::UpcastExistentialInst: {
|
||||
SILValue operand, operand2;
|
||||
unsigned Attr = 0;
|
||||
if (SI.getKind() == ValueKind::IndexRawPointerInst) {
|
||||
const IndexRawPointerInst *IRP = cast<IndexRawPointerInst>(&SI);
|
||||
operand = IRP->getBase();
|
||||
operand2 = IRP->getIndex();
|
||||
} else if (SI.getKind() == ValueKind::UpcastExistentialInst) {
|
||||
Attr = cast<UpcastExistentialInst>(&SI)->isTakeOfSrc();
|
||||
operand = cast<UpcastExistentialInst>(&SI)->getSrcExistential();
|
||||
operand2 = cast<UpcastExistentialInst>(&SI)->getDestExistential();
|
||||
} else {
|
||||
const IndexAddrInst *IAI = cast<IndexAddrInst>(&SI);
|
||||
operand = IAI->getBase();
|
||||
@@ -879,6 +884,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
||||
case ValueKind::ThickToObjCMetatypeInst:
|
||||
case ValueKind::ObjCToThickMetatypeInst:
|
||||
case ValueKind::ConvertFunctionInst:
|
||||
case ValueKind::UpcastExistentialRefInst:
|
||||
case ValueKind::ObjCMetatypeToObjectInst:
|
||||
case ValueKind::ObjCExistentialMetatypeToObjectInst:
|
||||
case ValueKind::ProjectBlockStorageInst: {
|
||||
|
||||
@@ -278,6 +278,8 @@ bb0(%0 : $*Runcible, %1 : $*protocol<Bendable, Runcible>):
|
||||
%4 = alloc_stack $protocol<Bendable, Runcible>
|
||||
// CHECK: copy_addr {{.*}} to [initialization] {{.*}} : $*protocol<Bendable, Runcible>
|
||||
%5 = copy_addr %2#1 to [initialization] %4#1 : $*protocol<Bendable, Runcible>
|
||||
// CHECK: upcast_existential [take] {{.*}} : $*protocol<Bendable, Runcible> to {{.*}} : $*Runcible
|
||||
%6 = upcast_existential [take] %4#1 : $*protocol<Bendable, Runcible> to %0 : $*Runcible
|
||||
%7 = tuple ()
|
||||
// CHECK: destroy_addr
|
||||
%8 = destroy_addr %4#1 : $*protocol<Bendable, Runcible>
|
||||
|
||||
@@ -200,7 +200,7 @@ func existentials(i: Int, dp: DerivedProtocol) {
|
||||
var e : SomeProtocol // expected-note {{variable defined here}}
|
||||
e.protoMe() // expected-error {{variable 'e' used before being initialized}}
|
||||
|
||||
var f : SomeProtocol = dp // ok, init'd by existential upcast.
|
||||
var f : SomeProtocol = dp // ok, init'd by upcast_existential.
|
||||
|
||||
var g : DerivedProtocol // expected-note {{variable defined here}}
|
||||
f = g // expected-error {{variable 'g' used before being initialized}}
|
||||
|
||||
@@ -254,6 +254,8 @@ bb0(%0 : $*Runcible, %1 : $*protocol<Bendable, Runcible>):
|
||||
%4 = alloc_stack $protocol<Bendable, Runcible>
|
||||
// CHECK: copy_addr {{.*}} to [initialization] {{.*}} : $*protocol<Bendable, Runcible>
|
||||
%5 = copy_addr %2#1 to [initialization] %4#1 : $*protocol<Bendable, Runcible>
|
||||
// CHECK: upcast_existential [take] {{.*}} : $*protocol<Bendable, Runcible> to {{.*}} : $*Runcible
|
||||
%6 = upcast_existential [take] %4#1 : $*protocol<Bendable, Runcible> to %0 : $*Runcible
|
||||
%7 = tuple ()
|
||||
// CHECK: destroy_addr
|
||||
%8 = destroy_addr %4#1 : $*protocol<Bendable, Runcible>
|
||||
|
||||
@@ -95,9 +95,9 @@
|
||||
"enum_is_tag")
|
||||
'words) . font-lock-keyword-face)
|
||||
;; Protocol and Protocol Composition Types
|
||||
`(,(regexp-opt '("init_existential" "deinit_existential"
|
||||
`(,(regexp-opt '("init_existential" "upcast_existential" "deinit_existential"
|
||||
"project_existential" "open_existential"
|
||||
"init_existential_ref"
|
||||
"init_existential_ref" "upcast_existential_ref"
|
||||
"project_existential_ref" "open_existential_ref")
|
||||
'words) . font-lock-keyword-face)
|
||||
;; Unchecked Conversions
|
||||
|
||||
@@ -32,7 +32,7 @@ syn keyword swiftKeyword apply partial_apply skipwhite
|
||||
syn keyword swiftKeyword metatype value_metatype existential_metatype skipwhite
|
||||
syn keyword swiftKeyword retain_value release_value tuple tuple_extract tuple_element_addr struct struct_extract struct_element_addr ref_element_addr skipwhite
|
||||
syn keyword swiftKeyword init_enum_data_addr unchecked_enum_data unchecked_take_enum_data_addr inject_enum_addr skipwhite
|
||||
syn keyword swiftKeyword init_existential deinit_existential project_existential open_existential init_existential_ref project_existential_ref open_existential_ref skipwhite
|
||||
syn keyword swiftKeyword init_existential upcast_existential deinit_existential project_existential open_existential init_existential_ref upcast_existential_ref project_existential_ref open_existential_ref skipwhite
|
||||
syn keyword swiftKeyword upcast address_to_pointer pointer_to_address unchecked_addr_cast unchecked_ref_cast ref_to_raw_pointer raw_pointer_to_ref convert_function thick_to_objc_metatype objc_to_thick_metatype thin_to_thick_function is_nonnull unchecked_ref_bit_cast unchecked_trivial_bit_cast skipwhite
|
||||
syn keyword swiftKeyword unconditional_checked_cast skipwhite
|
||||
syn keyword swiftKeyword cond_fail skipwhite
|
||||
|
||||
Reference in New Issue
Block a user