17
17
#ifndef SWIFT_SIL_SILCLONER_H
18
18
#define SWIFT_SIL_SILCLONER_H
19
19
20
+ #include " swift/AST/ProtocolConformance.h"
20
21
#include " swift/SIL/SILOpenedArchetypesTracker.h"
21
22
#include " swift/SIL/SILBuilder.h"
22
23
#include " swift/SIL/SILDebugScope.h"
@@ -94,7 +95,7 @@ class SILCloner : protected SILVisitor<ImplClass> {
94
95
const SILDebugScope *remapScope (const SILDebugScope *DS) { return DS; }
95
96
SILType remapType (SILType Ty) { return Ty; }
96
97
CanType remapASTType (CanType Ty) { return Ty; }
97
- ProtocolConformanceRef remapConformance (CanType Ty, ProtocolConformanceRef C){
98
+ ProtocolConformanceRef remapConformance (Type Ty, ProtocolConformanceRef C){
98
99
return C;
99
100
}
100
101
SILValue remapValue (SILValue Value);
@@ -108,37 +109,12 @@ class SILCloner : protected SILVisitor<ImplClass> {
108
109
const SILDebugScope *getOpScope (const SILDebugScope *DS) {
109
110
return asImpl ().remapScope (DS);
110
111
}
111
- Substitution getOpSubstitution (Substitution sub) {
112
- return asImpl ().remapSubstitution (sub);
113
- }
114
- Substitution remapSubstitution (Substitution sub) {
115
- CanType newReplacement =
116
- asImpl ().getOpASTType (sub.getReplacement ()->getCanonicalType ());
117
-
118
- return Substitution (newReplacement, sub.getConformances ());
119
- }
120
- SubstitutionList getOpSubstitutions (SubstitutionList Subs) {
121
- MutableArrayRef<Substitution> newSubsBuf;
122
-
123
- auto copySubs = [&]{
124
- if (!newSubsBuf.empty ())
125
- return ;
126
- newSubsBuf = getBuilder ().getASTContext ()
127
- .template Allocate <Substitution>(Subs.size ());
128
- memcpy (newSubsBuf.data (), Subs.data (),
129
- sizeof (Substitution) * Subs.size ());
130
- Subs = newSubsBuf;
131
- };
132
-
133
- for (unsigned i = 0 , e = Subs.size (); i < e; ++i) {
134
- Substitution newSub = asImpl ().getOpSubstitution (Subs[i]);
135
- if (newSub != Subs[i]) {
136
- copySubs ();
137
- newSubsBuf[i] = newSub;
138
- }
112
+ SmallVector<Substitution, 4 > getOpSubstitutions (SubstitutionList Subs) {
113
+ SmallVector<Substitution, 4 > NewSubs;
114
+ for (auto Sub : Subs) {
115
+ NewSubs.push_back (getOpSubstitution (Sub));
139
116
}
140
-
141
- return Subs;
117
+ return NewSubs;
142
118
}
143
119
144
120
SILType getTypeInClonedContext (SILType Ty) {
@@ -152,15 +128,15 @@ class SILCloner : protected SILVisitor<ImplClass> {
152
128
return asImpl ().remapType (Ty);
153
129
}
154
130
155
- CanType getASTTypeInClonedContext (CanType ty) {
131
+ CanType getASTTypeInClonedContext (Type ty) {
156
132
// Do not substitute opened existential types, if we do not have any.
157
133
if (!ty->hasOpenedExistential ())
158
- return ty;
134
+ return ty-> getCanonicalType () ;
159
135
// Do not substitute opened existential types, if it is not required.
160
136
// This is often the case when cloning basic blocks inside the same
161
137
// function.
162
138
if (OpenedExistentialSubs.empty ())
163
- return ty;
139
+ return ty-> getCanonicalType () ;
164
140
165
141
return ty.transform (
166
142
[&](Type t) -> Type {
@@ -181,32 +157,46 @@ class SILCloner : protected SILVisitor<ImplClass> {
181
157
return t;
182
158
})->getCanonicalType ();
183
159
}
160
+
184
161
CanType getOpASTType (CanType ty) {
185
162
ty = getASTTypeInClonedContext (ty);
186
163
return asImpl ().remapASTType (ty);
187
164
}
188
165
189
- // / Remap an entire set of conformances.
190
- // /
191
- // / Returns the passed-in conformances array if none of the elements
192
- // / changed.
193
- ArrayRef<ProtocolConformanceRef> getOpConformances (CanType type,
194
- ArrayRef<ProtocolConformanceRef> oldConformances) {
195
- Substitution sub (type, oldConformances);
196
- Substitution mappedSub = asImpl ().remapSubstitution (sub);
197
- ArrayRef<ProtocolConformanceRef> newConformances =
198
- mappedSub.getConformances ();
199
-
200
- // Use the existing conformances array if possible.
201
- if (oldConformances == newConformances)
202
- return oldConformances;
203
-
204
- return type->getASTContext ().AllocateCopy (newConformances);
166
+ ProtocolConformanceRef getOpConformance (Type ty,
167
+ ProtocolConformanceRef conformance) {
168
+ auto newConformance =
169
+ conformance.subst (ty,
170
+ [&](SubstitutableType *t) -> Type {
171
+ if (t->isOpenedExistential ()) {
172
+ auto found = OpenedExistentialSubs.find (
173
+ t->castTo <ArchetypeType>());
174
+ if (found != OpenedExistentialSubs.end ())
175
+ return found->second ;
176
+ return t;
177
+ }
178
+ return t;
179
+ },
180
+ MakeAbstractConformanceForGenericType ());
181
+ return asImpl ().remapConformance (getASTTypeInClonedContext (ty),
182
+ newConformance);
205
183
}
206
184
207
- ProtocolConformanceRef getOpConformance (CanType ty,
208
- ProtocolConformanceRef conformance) {
209
- return asImpl ().remapConformance (ty, conformance);
185
+ ArrayRef<ProtocolConformanceRef>
186
+ getOpConformances (Type ty,
187
+ ArrayRef<ProtocolConformanceRef> conformances) {
188
+ SmallVector<ProtocolConformanceRef, 4 > newConformances;
189
+ for (auto conformance : conformances)
190
+ newConformances.push_back (getOpConformance (ty, conformance));
191
+ return ty->getASTContext ().AllocateCopy (newConformances);
192
+ }
193
+
194
+ Substitution getOpSubstitution (Substitution sub) {
195
+ CanType newReplacement =
196
+ getOpASTType (sub.getReplacement ()->getCanonicalType ());
197
+ auto conformances = getOpConformances (sub.getReplacement (),
198
+ sub.getConformances ());
199
+ return Substitution (newReplacement, conformances);
210
200
}
211
201
212
202
SILValue getOpValue (SILValue Value) {
@@ -538,9 +528,10 @@ SILCloner<ImplClass>::visitAllocExistentialBoxInst(
538
528
AllocExistentialBoxInst *Inst) {
539
529
auto origExistentialType = Inst->getExistentialType ();
540
530
auto origFormalType = Inst->getFormalConcreteType ();
541
-
542
- auto conformances =getOpConformances (origFormalType, Inst->getConformances ());
543
-
531
+
532
+ auto conformances = getOpConformances (origFormalType,
533
+ Inst->getConformances ());
534
+
544
535
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
545
536
doPostProcess (Inst,
546
537
getBuilder ().createAllocExistentialBox (getOpLocation (Inst->getLoc ()),
@@ -1447,7 +1438,7 @@ SILCloner<ImplClass>::visitClassMethodInst(ClassMethodInst *Inst) {
1447
1438
getBuilder ().createClassMethod (getOpLocation (Inst->getLoc ()),
1448
1439
getOpValue (Inst->getOperand ()),
1449
1440
Inst->getMember (),
1450
- getOpType ( Inst->getType () ),
1441
+ Inst->getType (),
1451
1442
Inst->isVolatile ()));
1452
1443
}
1453
1444
@@ -1459,25 +1450,37 @@ SILCloner<ImplClass>::visitSuperMethodInst(SuperMethodInst *Inst) {
1459
1450
getBuilder ().createSuperMethod (getOpLocation (Inst->getLoc ()),
1460
1451
getOpValue (Inst->getOperand ()),
1461
1452
Inst->getMember (),
1462
- getOpType ( Inst->getType () ),
1453
+ Inst->getType (),
1463
1454
Inst->isVolatile ()));
1464
1455
}
1465
1456
1466
1457
template <typename ImplClass>
1467
1458
void
1468
1459
SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
1469
- auto conformance =
1470
- getOpConformance (Inst->getLookupType (), Inst->getConformance ());
1471
1460
auto lookupType = Inst->getLookupType ();
1461
+ auto conformance = getOpConformance (lookupType, Inst->getConformance ());
1472
1462
auto newLookupType = getOpASTType (lookupType);
1463
+
1464
+ if (conformance.isConcrete ()) {
1465
+ CanType Ty = conformance.getConcrete ()->getType ()->getCanonicalType ();
1466
+
1467
+ if (Ty != newLookupType) {
1468
+ assert (Ty->isExactSuperclassOf (newLookupType, nullptr ) &&
1469
+ " Should only create upcasts for sub class." );
1470
+
1471
+ // We use the super class as the new look up type.
1472
+ newLookupType = Ty;
1473
+ }
1474
+ }
1475
+
1473
1476
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
1474
1477
doPostProcess (
1475
1478
Inst,
1476
1479
getBuilder ()
1477
1480
.createWitnessMethod (
1478
1481
getOpLocation (Inst->getLoc ()),
1479
1482
newLookupType, conformance,
1480
- Inst->getMember (), getOpType ( Inst->getType () ),
1483
+ Inst->getMember (), Inst->getType (),
1481
1484
Inst->isVolatile ()));
1482
1485
}
1483
1486
@@ -1601,7 +1604,10 @@ template<typename ImplClass>
1601
1604
void
1602
1605
SILCloner<ImplClass>::visitInitExistentialAddrInst(InitExistentialAddrInst *Inst) {
1603
1606
CanType origFormalType = Inst->getFormalConcreteType ();
1604
- auto conformances =getOpConformances (origFormalType, Inst->getConformances ());
1607
+
1608
+ auto conformances = getOpConformances (origFormalType,
1609
+ Inst->getConformances ());
1610
+
1605
1611
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
1606
1612
doPostProcess (Inst,
1607
1613
getBuilder ().createInitExistentialAddr (getOpLocation (Inst->getLoc ()),
@@ -1615,8 +1621,10 @@ template <typename ImplClass>
1615
1621
void SILCloner<ImplClass>::visitInitExistentialOpaqueInst(
1616
1622
InitExistentialOpaqueInst *Inst) {
1617
1623
CanType origFormalType = Inst->getFormalConcreteType ();
1618
- auto conformances =
1619
- getOpConformances (origFormalType, Inst->getConformances ());
1624
+
1625
+ auto conformances = getOpConformances (origFormalType,
1626
+ Inst->getConformances ());
1627
+
1620
1628
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
1621
1629
doPostProcess (Inst,
1622
1630
getBuilder ().createInitExistentialOpaque (
@@ -1629,8 +1637,10 @@ template<typename ImplClass>
1629
1637
void
1630
1638
SILCloner<ImplClass>::
1631
1639
visitInitExistentialMetatypeInst (InitExistentialMetatypeInst *Inst) {
1632
- auto conformances = getOpConformances (Inst->getFormalErasedObjectType (),
1640
+ auto origFormalType = Inst->getFormalErasedObjectType ();
1641
+ auto conformances = getOpConformances (origFormalType,
1633
1642
Inst->getConformances ());
1643
+
1634
1644
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
1635
1645
doPostProcess (Inst,
1636
1646
getBuilder ().createInitExistentialMetatype (getOpLocation (Inst->getLoc ()),
@@ -1644,7 +1654,9 @@ void
1644
1654
SILCloner<ImplClass>::
1645
1655
visitInitExistentialRefInst (InitExistentialRefInst *Inst) {
1646
1656
CanType origFormalType = Inst->getFormalConcreteType ();
1647
- auto conformances =getOpConformances (origFormalType, Inst->getConformances ());
1657
+ auto conformances = getOpConformances (origFormalType,
1658
+ Inst->getConformances ());
1659
+
1648
1660
getBuilder ().setCurrentDebugScope (getOpScope (Inst->getDebugScope ()));
1649
1661
doPostProcess (Inst,
1650
1662
getBuilder ().createInitExistentialRef (getOpLocation (Inst->getLoc ()),
0 commit comments