@@ -44,13 +44,15 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
44
44
bool FileHasEntryPoint;
45
45
bool SILSerializeWitnessTables;
46
46
47
+ bool InsideAbstractStorageDecl = false ;
48
+
47
49
void addSymbol (StringRef name) {
48
50
auto isNewValue = Symbols.insert (name).second ;
49
51
(void )isNewValue;
50
52
assert (isNewValue && " already inserted" );
51
53
}
52
54
53
- void addSymbol (SILDeclRef declRef, bool checkSILOnly = true );
55
+ void addSymbol (SILDeclRef declRef);
54
56
55
57
void addSymbol (LinkEntity entity) {
56
58
auto linkage =
@@ -85,8 +87,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
85
87
addMembers (ED->getMembers ());
86
88
else if (auto NTD = dyn_cast<NominalTypeDecl>(D))
87
89
addMembers (NTD->getMembers ());
88
- else if (auto VD = dyn_cast<VarDecl >(D))
89
- VD ->getAllAccessorFunctions (members);
90
+ else if (auto ASD = dyn_cast<AbstractStorageDecl >(D))
91
+ ASD ->getAllAccessorFunctions (members);
90
92
91
93
for (auto member : members) {
92
94
ASTVisitor::visit (member);
@@ -103,12 +105,6 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
103
105
// any information here is encoded elsewhere
104
106
}
105
107
106
- void visitSubscriptDecl (SubscriptDecl *SD) {
107
- // Any getters and setters etc. exist as independent FuncDecls in the AST,
108
- // so get processed elsewhere; subscripts don't have any symbols other than
109
- // these.
110
- }
111
-
112
108
void visitNominalTypeDecl (NominalTypeDecl *NTD);
113
109
114
110
void visitClassDecl (ClassDecl *CD);
@@ -117,6 +113,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
117
113
118
114
void visitProtocolDecl (ProtocolDecl *PD);
119
115
116
+ void visitAbstractStorageDecl (AbstractStorageDecl *ASD);
117
+
120
118
void visitVarDecl (VarDecl *VD);
121
119
122
120
void visitDecl (Decl *D) { visitMembers (D); }
@@ -138,13 +136,13 @@ void TBDGenVisitor::visitPatternBindingDecl(PatternBindingDecl *PBD) {
138
136
auto declRef =
139
137
SILDeclRef (var, SILDeclRef::Kind::StoredPropertyInitializer);
140
138
// Stored property initializers for public properties are currently
141
- // public, even when the initializer is marked as SIL only (transparent) .
142
- addSymbol (declRef, /* checkSILOnly= */ false );
139
+ // public.
140
+ addSymbol (declRef);
143
141
}
144
142
}
145
143
}
146
144
147
- void TBDGenVisitor::addSymbol (SILDeclRef declRef, bool checkSILOnly ) {
145
+ void TBDGenVisitor::addSymbol (SILDeclRef declRef) {
148
146
bool isPrivate = !hasPublicVisibility (declRef.getLinkage (ForDefinition));
149
147
// Even private methods of open classes (specifically, private methods that
150
148
// are in the vtable) have public symbols, because external subclasses
@@ -155,7 +153,6 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
155
153
// unconditionally, even if they're theoretically SIL only.
156
154
if (isPrivate) {
157
155
isPrivate = false ;
158
- checkSILOnly = false ;
159
156
}
160
157
break ;
161
158
case SubclassScope::Internal:
@@ -165,10 +162,9 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
165
162
if (isPrivate)
166
163
return ;
167
164
168
- // (Most) transparent things don't exist, even if they're public.
169
- // FIXME: isTransparent should really be "is SIL only".
170
- if (checkSILOnly && declRef.isTransparent ())
171
- return ;
165
+ // FIXME: this includes too many symbols. There are some that are considered
166
+ // SIL-only, but it isn't obvious how to determine this (e.g. it seems that
167
+ // many, but not all, transparent functions result in object-file symbols)
172
168
173
169
addSymbol (declRef.mangle ());
174
170
}
@@ -256,6 +252,14 @@ void TBDGenVisitor::visitValueDecl(ValueDecl *VD) {
256
252
}
257
253
258
254
void TBDGenVisitor::visitAbstractFunctionDecl (AbstractFunctionDecl *AFD) {
255
+ if (auto FD = dyn_cast<FuncDecl>(AFD)) {
256
+ // Accessors also appear nested inside the storage decl, which we treat as
257
+ // the canonical location, so skip if we've got an accessor that isn't
258
+ // inside the var decl.
259
+ if (FD->getAccessorStorageDecl () && !InsideAbstractStorageDecl)
260
+ return ;
261
+ }
262
+
259
263
// Default arguments (of public functions) are public symbols, as the default
260
264
// values are computed at the call site.
261
265
auto index = 0 ;
@@ -275,10 +279,14 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
275
279
visitValueDecl (AFD);
276
280
}
277
281
282
+ void TBDGenVisitor::visitAbstractStorageDecl (AbstractStorageDecl *ASD) {
283
+ assert (!InsideAbstractStorageDecl &&
284
+ " unexpected nesting of abstract storage decls" );
285
+ InsideAbstractStorageDecl = true ;
286
+ visitMembers (ASD);
287
+ InsideAbstractStorageDecl = false ;
288
+ }
278
289
void TBDGenVisitor::visitVarDecl (VarDecl *VD) {
279
- if (isPrivateDecl (VD))
280
- return ;
281
-
282
290
// statically/globally stored variables have some special handling.
283
291
if (VD->hasStorage () && isGlobalOrStaticVar (VD)) {
284
292
// The actual variable has a symbol.
@@ -289,11 +297,9 @@ void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
289
297
// despite otherwise looking like globals.
290
298
if (!FileHasEntryPoint || VD->isStatic ())
291
299
addSymbol (SILDeclRef (VD, SILDeclRef::Kind::GlobalAccessor));
292
-
293
- // In this case, the members of the VarDecl don't also appear as top-level
294
- // decls, so we need to explicitly walk them.
295
- visitMembers (VD);
296
300
}
301
+
302
+ visitAbstractStorageDecl (VD);
297
303
}
298
304
299
305
void TBDGenVisitor::visitNominalTypeDecl (NominalTypeDecl *NTD) {
0 commit comments