@@ -1258,7 +1258,7 @@ bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const {
12581258 // parent tuple has only one non-trivial field.
12591259 bool FoundNonTrivialField = false ;
12601260 SILType OpTy = getOperand ()->getType ();
1261- unsigned FieldNo = getFieldNo ();
1261+ unsigned FieldNo = getFieldIndex ();
12621262
12631263 // For each element index of the tuple...
12641264 for (unsigned i = 0 , e = getNumTupleElts (); i != e; ++i) {
@@ -1300,7 +1300,7 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
13001300 // Ok, we know that the elt we are extracting is non-trivial. Make sure that
13011301 // we have no other non-trivial elts.
13021302 SILType OpTy = getOperand ()->getType ();
1303- unsigned FieldNo = getFieldNo ();
1303+ unsigned FieldNo = getFieldIndex ();
13041304
13051305 // For each element index of the tuple...
13061306 for (unsigned i = 0 , e = getNumTupleElts (); i != e; ++i) {
@@ -1323,18 +1323,43 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
13231323 return true ;
13241324}
13251325
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 ()) {
13291336 if (field == property) {
1330- SILInstruction::Bits.FieldIndexCacheBase .FieldIndex = i;
1331- return i;
1337+ return index;
13321338 }
1333- ++i ;
1339+ ++index ;
13341340 }
13351341 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;
13381363}
13391364
13401365// FIXME: this should be cached during cacheFieldIndex().
0 commit comments