@@ -5973,19 +5973,22 @@ VarDecl *getIndexedField(NominalTypeDecl *decl, unsigned index);
5973
5973
// / because it would allow constant time lookup of either the VarDecl or the
5974
5974
// / index from a single pointer without referring back to a projection
5975
5975
// / instruction.
5976
- class FieldIndexCacheBase : public SingleValueInstruction {
5976
+ template <typename ParentTy>
5977
+ class FieldIndexCacheBase : public ParentTy {
5977
5978
enum : unsigned { InvalidFieldIndex = ~unsigned (0 ) };
5978
5979
5979
5980
VarDecl *field;
5980
5981
5981
5982
public:
5983
+ template <typename ... ArgTys>
5982
5984
FieldIndexCacheBase (SILInstructionKind kind, SILDebugLocation loc,
5983
- SILType type, VarDecl *field)
5984
- : SingleValueInstruction(kind, loc, type), field(field) {
5985
+ SILType type, VarDecl *field, ArgTys &&... extraArgs)
5986
+ : ParentTy(kind, loc, type, std::forward<ArgTys>(extraArgs)...),
5987
+ field (field) {
5985
5988
SILInstruction::Bits.FieldIndexCacheBase .FieldIndex = InvalidFieldIndex;
5986
5989
// This needs to be a concrete class to hold bitfield information. However,
5987
5990
// it should only be extended by UnaryInstructions.
5988
- assert (getNumOperands () == 1 );
5991
+ assert (ParentTy:: getNumOperands () == 1 );
5989
5992
}
5990
5993
5991
5994
VarDecl *getField () const { return field; }
@@ -5999,7 +6002,8 @@ class FieldIndexCacheBase : public SingleValueInstruction {
5999
6002
}
6000
6003
6001
6004
NominalTypeDecl *getParentDecl () const {
6002
- auto s = getOperand (0 )->getType ().getNominalOrBoundGenericNominal ();
6005
+ auto s =
6006
+ ParentTy::getOperand (0 )->getType ().getNominalOrBoundGenericNominal ();
6003
6007
assert (s);
6004
6008
return s;
6005
6009
}
@@ -6012,13 +6016,17 @@ class FieldIndexCacheBase : public SingleValueInstruction {
6012
6016
}
6013
6017
6014
6018
private:
6015
- unsigned cacheFieldIndex ();
6019
+ unsigned cacheFieldIndex () {
6020
+ unsigned index = swift::getFieldIndex (getParentDecl (), getField ());
6021
+ SILInstruction::Bits.FieldIndexCacheBase .FieldIndex = index;
6022
+ return index;
6023
+ }
6016
6024
};
6017
6025
6018
6026
// / Extract a physical, fragile field out of a value of struct type.
6019
6027
class StructExtractInst
6020
6028
: public UnaryInstructionBase<SILInstructionKind::StructExtractInst,
6021
- FieldIndexCacheBase> {
6029
+ FieldIndexCacheBase<SingleValueInstruction> > {
6022
6030
friend SILBuilder;
6023
6031
6024
6032
StructExtractInst (SILDebugLocation DebugLoc, SILValue Operand, VarDecl *Field,
@@ -6043,7 +6051,7 @@ class StructExtractInst
6043
6051
// / Derive the address of a physical field from the address of a struct.
6044
6052
class StructElementAddrInst
6045
6053
: public UnaryInstructionBase<SILInstructionKind::StructElementAddrInst,
6046
- FieldIndexCacheBase> {
6054
+ FieldIndexCacheBase<SingleValueInstruction> > {
6047
6055
friend SILBuilder;
6048
6056
6049
6057
StructElementAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
@@ -6060,7 +6068,7 @@ class StructElementAddrInst
6060
6068
// / type instance.
6061
6069
class RefElementAddrInst
6062
6070
: public UnaryInstructionBase<SILInstructionKind::RefElementAddrInst,
6063
- FieldIndexCacheBase> {
6071
+ FieldIndexCacheBase<SingleValueInstruction> > {
6064
6072
friend SILBuilder;
6065
6073
6066
6074
RefElementAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
0 commit comments