@@ -1258,7 +1258,7 @@ bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const {
1258
1258
// parent tuple has only one non-trivial field.
1259
1259
bool FoundNonTrivialField = false ;
1260
1260
SILType OpTy = getOperand ()->getType ();
1261
- unsigned FieldNo = getFieldNo ();
1261
+ unsigned FieldNo = getFieldIndex ();
1262
1262
1263
1263
// For each element index of the tuple...
1264
1264
for (unsigned i = 0 , e = getNumTupleElts (); i != e; ++i) {
@@ -1300,7 +1300,7 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
1300
1300
// Ok, we know that the elt we are extracting is non-trivial. Make sure that
1301
1301
// we have no other non-trivial elts.
1302
1302
SILType OpTy = getOperand ()->getType ();
1303
- unsigned FieldNo = getFieldNo ();
1303
+ unsigned FieldNo = getFieldIndex ();
1304
1304
1305
1305
// For each element index of the tuple...
1306
1306
for (unsigned i = 0 , e = getNumTupleElts (); i != e; ++i) {
@@ -1323,18 +1323,43 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
1323
1323
return true ;
1324
1324
}
1325
1325
1326
- unsigned FieldIndexCacheBase::cacheFieldIndex () {
1327
- unsigned i = 0 ;
1328
- for (VarDecl *property : getParentDecl ()->getStoredProperties ()) {
1326
+ // / Get a unique index for a struct or class field in layout order.
1327
+ unsigned swift::getFieldIndex (NominalTypeDecl *decl, VarDecl *field) {
1328
+ unsigned index = 0 ;
1329
+ if (auto *classDecl = dyn_cast<ClassDecl>(decl)) {
1330
+ for (auto *superDecl = classDecl->getSuperclassDecl (); superDecl != nullptr ;
1331
+ superDecl = superDecl->getSuperclassDecl ()) {
1332
+ index += superDecl->getStoredProperties ().size ();
1333
+ }
1334
+ }
1335
+ for (VarDecl *property : decl->getStoredProperties ()) {
1329
1336
if (field == property) {
1330
- SILInstruction::Bits.FieldIndexCacheBase .FieldIndex = i;
1331
- return i;
1337
+ return index;
1332
1338
}
1333
- ++i ;
1339
+ ++index ;
1334
1340
}
1335
1341
llvm_unreachable (" The field decl for a struct_extract, struct_element_addr, "
1336
- " or ref_element_addr must be an accessible stored property "
1337
- " of the operand's type" );
1342
+ " or ref_element_addr must be an accessible stored "
1343
+ " property of the operand type" );
1344
+ }
1345
+
1346
+ // / Get the property for a struct or class by its unique index.
1347
+ VarDecl *swift::getIndexedField (NominalTypeDecl *decl, unsigned index) {
1348
+ if (auto *classDecl = dyn_cast<ClassDecl>(decl)) {
1349
+ for (auto *superDecl = classDecl->getSuperclassDecl (); superDecl != nullptr ;
1350
+ superDecl = superDecl->getSuperclassDecl ()) {
1351
+ assert (index >= superDecl->getStoredProperties ().size ()
1352
+ && " field index cannot refer to a superclass field" );
1353
+ index -= superDecl->getStoredProperties ().size ();
1354
+ }
1355
+ }
1356
+ return decl->getStoredProperties ()[index];
1357
+ }
1358
+
1359
+ unsigned FieldIndexCacheBase::cacheFieldIndex () {
1360
+ unsigned index = ::getFieldIndex (getParentDecl (), getField ());
1361
+ SILInstruction::Bits.FieldIndexCacheBase .FieldIndex = index;
1362
+ return index;
1338
1363
}
1339
1364
1340
1365
// FIXME: this should be cached during cacheFieldIndex().
0 commit comments