Skip to content

Commit 2e635e9

Browse files
committed
Sema: Add @_hasInitialValue and @_hasStorage in typeCheckDecl() not validateDecl()
We only ever use this in TBDGen and interface printing, and we only ever generate TBD files or print interfaces for declarations in primary files, so let's avoid unnecessary work in validateDecl(). Eventually we want validateDecl() to be replaced with a getInterfaceType() request, so adding new attributes in this path (or other side effects in general) is a big no-no.
1 parent 99a45b0 commit 2e635e9

File tree

5 files changed

+25
-21
lines changed

5 files changed

+25
-21
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,7 +2484,6 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
24842484

24852485
bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
24862486
unsigned patternNumber) {
2487-
auto &ctx = PBD->getASTContext();
24882487
const auto &pbe = PBD->getPatternList()[patternNumber];
24892488
Pattern *pattern = PBD->getPattern(patternNumber);
24902489
Expr *init = PBD->getInit(patternNumber);
@@ -2507,13 +2506,6 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
25072506
PBD->setPattern(patternNumber, pattern, initContext);
25082507
PBD->setInit(patternNumber, init);
25092508

2510-
// Add the attribute that preserves the "has an initializer" value across
2511-
// module generation, as required for TBDGen.
2512-
PBD->getPattern(patternNumber)->forEachVariable([&](VarDecl *VD) {
2513-
if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasInitialValueAttr>())
2514-
VD->getAttrs().add(new (ctx) HasInitialValueAttr(/*IsImplicit=*/true));
2515-
});
2516-
25172509
if (!hadError) {
25182510
// If we're performing an binding to a weak or unowned variable from a
25192511
// constructor call, emit a warning that the instance will be immediately

lib/Sema/TypeCheckDecl.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,14 +2120,17 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
21202120
}
21212121

21222122
void visitBoundVariable(VarDecl *VD) {
2123+
// WARNING: Anything you put in this function will only be run when the
2124+
// VarDecl is fully type-checked within its own file. It will NOT be run
2125+
// when the VarDecl is merely used from another file.
21232126
TC.validateDecl(VD);
21242127

2125-
// Set up accessors.
2128+
// Set up accessors, also lowering lazy and @NSManaged properties.
21262129
maybeAddAccessorsToStorage(VD);
21272130

2128-
// WARNING: Anything you put in this function will only be run when the
2129-
// VarDecl is fully type-checked within its own file. It will NOT be run
2130-
// when the VarDecl is merely used from another file.
2131+
// Add the '@_hasStorage' attribute if this property is stored.
2132+
if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
2133+
VD->getAttrs().add(new (TC.Context) HasStorageAttr(/*isImplicit=*/true));
21312134

21322135
// Reject cases where this is a variable that has storage but it isn't
21332136
// allowed.
@@ -2277,6 +2280,19 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
22772280
PBD->setInit(i, defaultInit);
22782281
}
22792282
}
2283+
2284+
if (PBD->getInit(i)) {
2285+
// Add the attribute that preserves the "has an initializer" value across
2286+
// module generation, as required for TBDGen.
2287+
PBD->getPattern(i)->forEachVariable([&](VarDecl *VD) {
2288+
if (VD->hasStorage() &&
2289+
!VD->getAttrs().hasAttribute<HasInitialValueAttr>()) {
2290+
auto *attr = new (TC.Context) HasInitialValueAttr(
2291+
/*IsImplicit=*/true);
2292+
VD->getAttrs().add(attr);
2293+
}
2294+
});
2295+
}
22802296
}
22812297

22822298
bool isInSILMode = false;
@@ -3687,10 +3703,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
36873703
auto *VD = cast<VarDecl>(D);
36883704
auto *PBD = VD->getParentPatternBinding();
36893705

3690-
// Add the '@_hasStorage' attribute if this property is stored.
3691-
if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
3692-
VD->getAttrs().add(new (Context) HasStorageAttr(/*isImplicit=*/true));
3693-
36943706
// Note that we need to handle the fact that some VarDecls don't
36953707
// have a PatternBindingDecl, for example the iterator in a
36963708
// 'for ... in ...' loop.

test/SIL/Parser/final.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-swift-frontend %s -emit-silgen | %FileCheck %s
22

33
// CHECK: final class Rect
4-
// CHECK: @_hasInitialValue @_hasStorage final var orgx: Double
4+
// CHECK: @_hasStorage @_hasInitialValue final var orgx: Double
55
final class Rect {
66
var orgx = 0.0
77
}

test/attr/attr_objc.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ class infer_instanceVar1 {
839839
}
840840

841841
var observingAccessorsVar1: Int {
842-
// CHECK: @_hasStorage @objc var observingAccessorsVar1: Int {
842+
// CHECK: @objc @_hasStorage var observingAccessorsVar1: Int {
843843
willSet {}
844844
// CHECK-NEXT: {{^}} @objc get
845845
didSet {}
@@ -1709,7 +1709,7 @@ class HasNSManaged {
17091709

17101710
@NSManaged
17111711
var goodManaged: Class_ObjC1
1712-
// CHECK-LABEL: {{^}} @objc @NSManaged @_hasStorage dynamic var goodManaged: Class_ObjC1 {
1712+
// CHECK-LABEL: {{^}} @objc @NSManaged dynamic var goodManaged: Class_ObjC1 {
17131713
// CHECK-NEXT: {{^}} @objc get
17141714
// CHECK-NEXT: {{^}} @objc set
17151715
// CHECK-NEXT: {{^}} }
@@ -1719,7 +1719,7 @@ class HasNSManaged {
17191719
// expected-error@-1 {{property cannot be marked @NSManaged because its type cannot be represented in Objective-C}}
17201720
// expected-note@-2 {{Swift structs cannot be represented in Objective-C}}
17211721
// expected-error@-3{{'dynamic' property 'badManaged' must also be '@objc'}}
1722-
// CHECK-LABEL: {{^}} @NSManaged @_hasStorage var badManaged: PlainStruct {
1722+
// CHECK-LABEL: {{^}} @NSManaged var badManaged: PlainStruct {
17231723
// CHECK-NEXT: {{^}} get
17241724
// CHECK-NEXT: {{^}} set
17251725
// CHECK-NEXT: {{^}} }

test/attr/hasInitialValue.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class C {
1212
// CHECK: {{^}} @_implicitly_unwrapped_optional @_hasInitialValue var iuo: Int!
1313
var iuo: Int!
1414

15-
// CHECK: {{^}} @_hasStorage lazy var lazyIsntARealInit: Int
15+
// CHECK: {{^}} lazy var lazyIsntARealInit: Int
1616
lazy var lazyIsntARealInit: Int = 0
1717

1818
init() {

0 commit comments

Comments
 (0)