Skip to content

Commit a560ea1

Browse files
committed
[TBDGen] Include all transparent symbols.
This is a vast overestimate, but is better than missing some. rdar://problem/32254773
1 parent 2c6e365 commit a560ea1

File tree

4 files changed

+33
-27
lines changed

4 files changed

+33
-27
lines changed

lib/TBDGen/TBDGen.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
4444
bool FileHasEntryPoint;
4545
bool SILSerializeWitnessTables;
4646

47+
bool InsideAbstractStorageDecl = false;
48+
4749
void addSymbol(StringRef name) {
4850
auto isNewValue = Symbols.insert(name).second;
4951
(void)isNewValue;
5052
assert(isNewValue && "already inserted");
5153
}
5254

53-
void addSymbol(SILDeclRef declRef, bool checkSILOnly = true);
55+
void addSymbol(SILDeclRef declRef);
5456

5557
void addSymbol(LinkEntity entity) {
5658
auto linkage =
@@ -85,8 +87,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
8587
addMembers(ED->getMembers());
8688
else if (auto NTD = dyn_cast<NominalTypeDecl>(D))
8789
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);
9092

9193
for (auto member : members) {
9294
ASTVisitor::visit(member);
@@ -103,12 +105,6 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
103105
// any information here is encoded elsewhere
104106
}
105107

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-
112108
void visitNominalTypeDecl(NominalTypeDecl *NTD);
113109

114110
void visitClassDecl(ClassDecl *CD);
@@ -117,6 +113,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
117113

118114
void visitProtocolDecl(ProtocolDecl *PD);
119115

116+
void visitAbstractStorageDecl(AbstractStorageDecl *ASD);
117+
120118
void visitVarDecl(VarDecl *VD);
121119

122120
void visitDecl(Decl *D) { visitMembers(D); }
@@ -138,13 +136,13 @@ void TBDGenVisitor::visitPatternBindingDecl(PatternBindingDecl *PBD) {
138136
auto declRef =
139137
SILDeclRef(var, SILDeclRef::Kind::StoredPropertyInitializer);
140138
// 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);
143141
}
144142
}
145143
}
146144

147-
void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
145+
void TBDGenVisitor::addSymbol(SILDeclRef declRef) {
148146
bool isPrivate = !hasPublicVisibility(declRef.getLinkage(ForDefinition));
149147
// Even private methods of open classes (specifically, private methods that
150148
// are in the vtable) have public symbols, because external subclasses
@@ -155,7 +153,6 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
155153
// unconditionally, even if they're theoretically SIL only.
156154
if (isPrivate) {
157155
isPrivate = false;
158-
checkSILOnly = false;
159156
}
160157
break;
161158
case SubclassScope::Internal:
@@ -165,10 +162,9 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
165162
if (isPrivate)
166163
return;
167164

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)
172168

173169
addSymbol(declRef.mangle());
174170
}
@@ -256,6 +252,14 @@ void TBDGenVisitor::visitValueDecl(ValueDecl *VD) {
256252
}
257253

258254
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+
259263
// Default arguments (of public functions) are public symbols, as the default
260264
// values are computed at the call site.
261265
auto index = 0;
@@ -275,10 +279,14 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
275279
visitValueDecl(AFD);
276280
}
277281

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+
}
278289
void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
279-
if (isPrivateDecl(VD))
280-
return;
281-
282290
// statically/globally stored variables have some special handling.
283291
if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
284292
// The actual variable has a symbol.
@@ -289,11 +297,9 @@ void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
289297
// despite otherwise looking like globals.
290298
if (!FileHasEntryPoint || VD->isStatic())
291299
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);
296300
}
301+
302+
visitAbstractStorageDecl(VD);
297303
}
298304

299305
void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {

test/TBD/global.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
1+
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
22

33
public let publicLet: Int = 0
44
internal let internalLet: Int = 0

test/TBD/protocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
1+
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
22

33
public protocol Public {
44
func publicMethod()

test/TBD/struct.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
1+
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
22

33
public struct PublicNothing {}
44

0 commit comments

Comments
 (0)