@@ -2472,11 +2472,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2472
2472
(void ) VD->isObjC ();
2473
2473
(void ) VD->isDynamic ();
2474
2474
2475
- // Make sure we finalize this declaration.
2476
- if (isa<ClassDecl>(VD) || isa<ProtocolDecl>(VD) ||
2477
- isa<AbstractStorageDecl>(VD))
2478
- TC.DeclsToFinalize .insert (VD);
2479
-
2480
2475
// If this is a member of a nominal type, don't allow it to have a name of
2481
2476
// "Type" or "Protocol" since we reserve the X.Type and X.Protocol
2482
2477
// expressions to mean something builtin to the language. We *do* allow
@@ -3155,6 +3150,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3155
3150
3156
3151
3157
3152
void visitClassDecl (ClassDecl *CD) {
3153
+ TC.DeclsToFinalize .insert (CD);
3154
+
3158
3155
TC.checkDeclAttributesEarly (CD);
3159
3156
3160
3157
checkUnsupportedNestedType (CD);
@@ -3499,7 +3496,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3499
3496
if (auto nominal = ED->getExtendedNominal ()) {
3500
3497
TC.validateDecl (nominal);
3501
3498
if (auto *classDecl = dyn_cast<ClassDecl>(nominal))
3502
- TC.requestNominalLayout (classDecl);
3499
+ TC.requestClassLayout (classDecl);
3503
3500
3504
3501
// Check the raw values of an enum, since we might synthesize
3505
3502
// RawRepresentable while checking conformances on this extension.
@@ -4143,14 +4140,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4143
4140
4144
4141
validateAttributes (*this , D);
4145
4142
4146
- // FIXME: IRGen likes to emit @objc protocol descriptors even if the
4147
- // protocol comes from a different module or translation unit.
4148
- //
4149
- // It would be nice if it didn't have to do that, then we could remove
4150
- // this case.
4151
- if (proto->isObjC ())
4152
- requestNominalLayout (proto);
4153
-
4154
4143
break ;
4155
4144
}
4156
4145
@@ -4522,14 +4511,6 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
4522
4511
return ;
4523
4512
proto->computeType ();
4524
4513
4525
- // FIXME: IRGen likes to emit @objc protocol descriptors even if the
4526
- // protocol comes from a different module or translation unit.
4527
- //
4528
- // It would be nice if it didn't have to do that, then we could remove
4529
- // this case.
4530
- if (proto->isObjC ())
4531
- requestNominalLayout (proto);
4532
-
4533
4514
break ;
4534
4515
}
4535
4516
case DeclKind::AssociatedType: {
@@ -4594,96 +4575,59 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
4594
4575
void TypeChecker::requestMemberLayout (ValueDecl *member) {
4595
4576
auto *dc = member->getDeclContext ();
4596
4577
if (auto *classDecl = dyn_cast<ClassDecl>(dc))
4597
- requestNominalLayout (classDecl);
4598
- if (auto *protocolDecl = dyn_cast<ProtocolDecl>(dc))
4599
- requestNominalLayout (protocolDecl);
4600
-
4601
- // If this represents (abstract) storage, form the appropriate accessors.
4602
- if (auto storage = dyn_cast<AbstractStorageDecl>(member))
4603
- DeclsToFinalize.insert (storage);
4578
+ requestClassLayout (classDecl);
4604
4579
}
4605
4580
4606
- void TypeChecker::requestNominalLayout (NominalTypeDecl *nominalDecl ) {
4607
- if (isa<SourceFile>(nominalDecl ->getModuleScopeContext ()))
4608
- DeclsToFinalize.insert (nominalDecl );
4581
+ void TypeChecker::requestClassLayout (ClassDecl *classDecl ) {
4582
+ if (isa<SourceFile>(classDecl ->getModuleScopeContext ()))
4583
+ DeclsToFinalize.insert (classDecl );
4609
4584
}
4610
4585
4611
4586
void TypeChecker::requestSuperclassLayout (ClassDecl *classDecl) {
4612
4587
if (auto *superclassDecl = classDecl->getSuperclassDecl ()) {
4613
4588
if (superclassDecl)
4614
- requestNominalLayout (superclassDecl);
4589
+ requestClassLayout (superclassDecl);
4615
4590
}
4616
4591
}
4617
4592
4618
- // / "Finalize" the type so that SILGen can make copies of it, call
4619
- // / methods on it, etc. This requires forcing enough computation so
4620
- // / that (for example) a class can layout its vtable or a struct can
4621
- // / be laid out in memory.
4622
- static void finalizeType (TypeChecker &TC, NominalTypeDecl *nominal) {
4623
- assert (!nominal->hasClangNode ());
4624
- assert (isa<SourceFile>(nominal->getModuleScopeContext ()));
4625
-
4626
- if (auto *CD = dyn_cast<ClassDecl>(nominal)) {
4627
- // We need to add implicit initializers and dtors because it
4628
- // affects vtable layout.
4629
- TC.addImplicitConstructors (CD);
4630
- CD->addImplicitDestructor ();
4631
-
4632
- // Force lowering of stored properties.
4633
- (void ) nominal->getStoredProperties ();
4634
- }
4635
-
4636
- if (isa<ClassDecl>(nominal) || isa<ProtocolDecl>(nominal)) {
4637
- for (auto *D : nominal->getMembers ()) {
4638
- if (auto *ASD = dyn_cast<AbstractStorageDecl>(D))
4639
- TC.DeclsToFinalize .insert (ASD);
4640
- }
4641
- }
4642
-
4643
- if (auto *CD = dyn_cast<ClassDecl>(nominal)) {
4644
- // We need the superclass vtable layout as well.
4645
- TC.requestSuperclassLayout (CD);
4593
+ void TypeChecker::finalizeDecl (ClassDecl *CD) {
4594
+ if (Context.Stats )
4595
+ Context.Stats ->getFrontendCounters ().NumDeclsFinalized ++;
4646
4596
4647
- auto forceConformance = [&](ProtocolDecl *protocol) {
4648
- if (auto ref = TypeChecker::conformsToProtocol (
4649
- CD->getDeclaredInterfaceType (), protocol, CD,
4650
- ConformanceCheckFlags::SkipConditionalRequirements,
4651
- SourceLoc ())) {
4652
- auto conformance = ref->getConcrete ();
4653
- if (conformance->getDeclContext () == CD &&
4654
- conformance->getState () == ProtocolConformanceState::Incomplete) {
4655
- TC.checkConformance (conformance->getRootNormalConformance ());
4656
- }
4657
- }
4658
- };
4597
+ assert (!CD->hasClangNode ());
4598
+ assert (isa<SourceFile>(CD->getModuleScopeContext ()));
4659
4599
4660
- // If the class is Encodable, Decodable or Hashable, force those
4661
- // conformances to ensure that the synthesized members appear in the vtable.
4662
- //
4663
- // FIXME: Generalize this to other protocols for which
4664
- // we can derive conformances.
4665
- forceConformance (TC.Context .getProtocol (KnownProtocolKind::Decodable));
4666
- forceConformance (TC.Context .getProtocol (KnownProtocolKind::Encodable));
4667
- forceConformance (TC.Context .getProtocol (KnownProtocolKind::Hashable));
4668
- }
4600
+ validateDecl (CD);
4669
4601
4670
- if (auto PD = dyn_cast<ProtocolDecl>(nominal)) {
4671
- for (auto *inherited : PD->getInheritedProtocols ())
4672
- TC.requestNominalLayout (inherited);
4673
- }
4674
- }
4602
+ // We need to add implicit initializers and dtors because it
4603
+ // affects vtable layout.
4604
+ addImplicitConstructors (CD);
4605
+ CD->addImplicitDestructor ();
4675
4606
4676
- void TypeChecker::finalizeDecl (ValueDecl *decl) {
4677
- if (Context.Stats )
4678
- Context.Stats ->getFrontendCounters ().NumDeclsFinalized ++;
4607
+ // We need the superclass vtable layout as well.
4608
+ requestSuperclassLayout (CD);
4679
4609
4680
- validateDecl (decl);
4610
+ auto forceConformance = [&](ProtocolDecl *protocol) {
4611
+ if (auto ref = TypeChecker::conformsToProtocol (
4612
+ CD->getDeclaredInterfaceType (), protocol, CD,
4613
+ ConformanceCheckFlags::SkipConditionalRequirements,
4614
+ SourceLoc ())) {
4615
+ auto conformance = ref->getConcrete ();
4616
+ if (conformance->getDeclContext () == CD &&
4617
+ conformance->getState () == ProtocolConformanceState::Incomplete) {
4618
+ checkConformance (conformance->getRootNormalConformance ());
4619
+ }
4620
+ }
4621
+ };
4681
4622
4682
- if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
4683
- finalizeType (*this , nominal);
4684
- } else if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
4685
- addExpectedOpaqueAccessorsToStorage (storage);
4686
- }
4623
+ // If the class is Encodable, Decodable or Hashable, force those
4624
+ // conformances to ensure that the synthesized members appear in the vtable.
4625
+ //
4626
+ // FIXME: Generalize this to other protocols for which
4627
+ // we can derive conformances.
4628
+ forceConformance (Context.getProtocol (KnownProtocolKind::Decodable));
4629
+ forceConformance (Context.getProtocol (KnownProtocolKind::Encodable));
4630
+ forceConformance (Context.getProtocol (KnownProtocolKind::Hashable));
4687
4631
}
4688
4632
4689
4633
// / Determine whether this is a "pass-through" typealias, which has the
0 commit comments