@@ -100,6 +100,52 @@ using AssociativityCacheType =
100
100
MACRO(NSNumber) \
101
101
MACRO(NSValue)
102
102
103
+ struct OverrideSignatureKey {
104
+ GenericSignature *baseMethodSig;
105
+ GenericSignature *derivedClassSig;
106
+ Type superclassTy;
107
+
108
+ OverrideSignatureKey (GenericSignature *baseMethodSignature,
109
+ GenericSignature *derivedClassSignature,
110
+ Type superclassType)
111
+ : baseMethodSig (baseMethodSignature),
112
+ derivedClassSig (derivedClassSignature), superclassTy (superclassType) {}
113
+ };
114
+
115
+ namespace llvm {
116
+ template <> struct DenseMapInfo <OverrideSignatureKey> {
117
+ using Type = swift::Type;
118
+ using GenericSignature = swift::GenericSignature;
119
+
120
+ static bool isEqual (const OverrideSignatureKey lhs,
121
+ const OverrideSignatureKey rhs) {
122
+ return lhs.baseMethodSig == rhs.baseMethodSig &&
123
+ lhs.derivedClassSig == rhs.derivedClassSig &&
124
+ lhs.superclassTy .getPointer () == rhs.superclassTy .getPointer ();
125
+ }
126
+
127
+ static inline OverrideSignatureKey getEmptyKey () {
128
+ return OverrideSignatureKey (DenseMapInfo<GenericSignature *>::getEmptyKey (),
129
+ DenseMapInfo<GenericSignature *>::getEmptyKey (),
130
+ DenseMapInfo<Type>::getEmptyKey ());
131
+ }
132
+
133
+ static inline OverrideSignatureKey getTombstoneKey () {
134
+ return OverrideSignatureKey (
135
+ DenseMapInfo<GenericSignature *>::getTombstoneKey (),
136
+ DenseMapInfo<GenericSignature *>::getTombstoneKey (),
137
+ DenseMapInfo<Type>::getTombstoneKey ());
138
+ }
139
+
140
+ static unsigned getHashValue (const OverrideSignatureKey &Val) {
141
+ return hash_combine (
142
+ DenseMapInfo<GenericSignature *>::getHashValue (Val.baseMethodSig ),
143
+ DenseMapInfo<GenericSignature *>::getHashValue (Val.derivedClassSig ),
144
+ DenseMapInfo<Type>::getHashValue (Val.superclassTy ));
145
+ }
146
+ };
147
+ } // namespace llvm
148
+
103
149
struct ASTContext ::Implementation {
104
150
Implementation ();
105
151
~Implementation ();
@@ -422,6 +468,8 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
422
468
llvm::FoldingSet<SILLayout> SILLayouts;
423
469
424
470
RC<syntax::SyntaxArena> TheSyntaxArena;
471
+
472
+ llvm::DenseMap<OverrideSignatureKey, GenericSignature *> overrideSigCache;
425
473
};
426
474
427
475
ASTContext::Implementation::Implementation ()
@@ -4337,6 +4385,108 @@ CanGenericSignature ASTContext::getExistentialSignature(CanType existential,
4337
4385
return genericSig;
4338
4386
}
4339
4387
4388
+ GenericSignature *ASTContext::getOverrideGenericSignature (ValueDecl *base,
4389
+ ValueDecl *derived) {
4390
+ auto baseGenericCtx = base->getAsGenericContext ();
4391
+ auto &ctx = base->getASTContext ();
4392
+
4393
+ if (!baseGenericCtx) {
4394
+ return nullptr ;
4395
+ }
4396
+
4397
+ auto baseClass = base->getDeclContext ()->getSelfClassDecl ();
4398
+
4399
+ if (!baseClass) {
4400
+ return nullptr ;
4401
+ }
4402
+
4403
+ auto derivedClass = derived->getDeclContext ()->getSelfClassDecl ();
4404
+ auto *baseClassSig = baseClass->getGenericSignature ();
4405
+
4406
+ if (!derivedClass) {
4407
+ return nullptr ;
4408
+ }
4409
+
4410
+ if (derivedClass->getSuperclass ().isNull ()) {
4411
+ return nullptr ;
4412
+ }
4413
+
4414
+ if (derivedClass->getGenericSignature () == nullptr &&
4415
+ !baseGenericCtx->isGeneric ()) {
4416
+ return nullptr ;
4417
+ }
4418
+
4419
+ auto subMap = derivedClass->getSuperclass ()->getContextSubstitutionMap (
4420
+ derivedClass->getModuleContext (), baseClass);
4421
+
4422
+ if (baseGenericCtx->getGenericSignature () == nullptr ) {
4423
+ return nullptr ;
4424
+ }
4425
+ unsigned derivedDepth = 0 ;
4426
+
4427
+ auto key = OverrideSignatureKey (baseGenericCtx->getGenericSignature (),
4428
+ derivedClass->getGenericSignature (),
4429
+ derivedClass->getSuperclass ());
4430
+
4431
+ if (getImpl ().overrideSigCache .find (key) !=
4432
+ getImpl ().overrideSigCache .end ()) {
4433
+ return getImpl ().overrideSigCache .lookup (key);
4434
+ }
4435
+
4436
+ if (auto *derivedSig = derivedClass->getGenericSignature ())
4437
+ derivedDepth = derivedSig->getGenericParams ().back ()->getDepth () + 1 ;
4438
+
4439
+ GenericSignatureBuilder builder (ctx);
4440
+ builder.addGenericSignature (derivedClass->getGenericSignature ());
4441
+
4442
+ if (auto derivedGenericCtx = derived->getAsGenericContext ()) {
4443
+ if (derivedGenericCtx->isGeneric ()) {
4444
+ for (auto param : *derivedGenericCtx->getGenericParams ()) {
4445
+ builder.addGenericParameter (param);
4446
+ }
4447
+ }
4448
+ }
4449
+
4450
+ auto source =
4451
+ GenericSignatureBuilder::FloatingRequirementSource::forAbstract ();
4452
+
4453
+ unsigned baseDepth = 0 ;
4454
+
4455
+ if (baseClassSig) {
4456
+ baseDepth = baseClassSig->getGenericParams ().back ()->getDepth () + 1 ;
4457
+ }
4458
+
4459
+ auto substFn = [&](SubstitutableType *type) -> Type {
4460
+ auto *gp = cast<GenericTypeParamType>(type);
4461
+
4462
+ if (gp->getDepth () < baseDepth) {
4463
+ return Type (gp).subst (subMap);
4464
+ }
4465
+
4466
+ return CanGenericTypeParamType::get (
4467
+ gp->getDepth () - baseDepth + derivedDepth, gp->getIndex (), ctx);
4468
+ };
4469
+
4470
+ auto lookupConformanceFn =
4471
+ [&](CanType depTy, Type substTy,
4472
+ ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
4473
+ if (auto conf = subMap.lookupConformance (depTy, proto))
4474
+ return conf;
4475
+
4476
+ return ProtocolConformanceRef (proto);
4477
+ };
4478
+
4479
+ for (auto reqt : baseGenericCtx->getGenericSignature ()->getRequirements ()) {
4480
+ if (auto substReqt = reqt.subst (substFn, lookupConformanceFn)) {
4481
+ builder.addRequirement (*substReqt, source, nullptr );
4482
+ }
4483
+ }
4484
+
4485
+ auto *genericSig = std::move (builder).computeGenericSignature (SourceLoc ());
4486
+ getImpl ().overrideSigCache .insert (std::make_pair (key, genericSig));
4487
+ return genericSig;
4488
+ }
4489
+
4340
4490
SILLayout *SILLayout::get (ASTContext &C,
4341
4491
CanGenericSignature Generics,
4342
4492
ArrayRef<SILField> Fields) {
0 commit comments