Skip to content

Yet more TBD. #10724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 33 additions & 27 deletions lib/TBDGen/TBDGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
bool FileHasEntryPoint;
bool SILSerializeWitnessTables;

bool InsideAbstractStorageDecl = false;

void addSymbol(StringRef name) {
auto isNewValue = Symbols.insert(name).second;
(void)isNewValue;
assert(isNewValue && "already inserted");
}

void addSymbol(SILDeclRef declRef, bool checkSILOnly = true);
void addSymbol(SILDeclRef declRef);

void addSymbol(LinkEntity entity) {
auto linkage =
Expand Down Expand Up @@ -85,8 +87,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
addMembers(ED->getMembers());
else if (auto NTD = dyn_cast<NominalTypeDecl>(D))
addMembers(NTD->getMembers());
else if (auto VD = dyn_cast<VarDecl>(D))
VD->getAllAccessorFunctions(members);
else if (auto ASD = dyn_cast<AbstractStorageDecl>(D))
ASD->getAllAccessorFunctions(members);

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

void visitSubscriptDecl(SubscriptDecl *SD) {
// Any getters and setters etc. exist as independent FuncDecls in the AST,
// so get processed elsewhere; subscripts don't have any symbols other than
// these.
}

void visitNominalTypeDecl(NominalTypeDecl *NTD);

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

void visitProtocolDecl(ProtocolDecl *PD);

void visitAbstractStorageDecl(AbstractStorageDecl *ASD);

void visitVarDecl(VarDecl *VD);

void visitDecl(Decl *D) { visitMembers(D); }
Expand All @@ -138,13 +136,13 @@ void TBDGenVisitor::visitPatternBindingDecl(PatternBindingDecl *PBD) {
auto declRef =
SILDeclRef(var, SILDeclRef::Kind::StoredPropertyInitializer);
// Stored property initializers for public properties are currently
// public, even when the initializer is marked as SIL only (transparent).
addSymbol(declRef, /*checkSILOnly=*/false);
// public.
addSymbol(declRef);
}
}
}

void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
void TBDGenVisitor::addSymbol(SILDeclRef declRef) {
bool isPrivate = !hasPublicVisibility(declRef.getLinkage(ForDefinition));
// Even private methods of open classes (specifically, private methods that
// are in the vtable) have public symbols, because external subclasses
Expand All @@ -155,7 +153,6 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
// unconditionally, even if they're theoretically SIL only.
if (isPrivate) {
isPrivate = false;
checkSILOnly = false;
}
break;
case SubclassScope::Internal:
Expand All @@ -165,10 +162,9 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
if (isPrivate)
return;

// (Most) transparent things don't exist, even if they're public.
// FIXME: isTransparent should really be "is SIL only".
if (checkSILOnly && declRef.isTransparent())
return;
// FIXME: this includes too many symbols. There are some that are considered
// SIL-only, but it isn't obvious how to determine this (e.g. it seems that
// many, but not all, transparent functions result in object-file symbols)

addSymbol(declRef.mangle());
}
Expand Down Expand Up @@ -256,6 +252,14 @@ void TBDGenVisitor::visitValueDecl(ValueDecl *VD) {
}

void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
if (auto FD = dyn_cast<FuncDecl>(AFD)) {
// Accessors also appear nested inside the storage decl, which we treat as
// the canonical location, so skip if we've got an accessor that isn't
// inside the var decl.
if (FD->getAccessorStorageDecl() && !InsideAbstractStorageDecl)
return;
}

// Default arguments (of public functions) are public symbols, as the default
// values are computed at the call site.
auto index = 0;
Expand All @@ -275,25 +279,27 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
visitValueDecl(AFD);
}

void TBDGenVisitor::visitAbstractStorageDecl(AbstractStorageDecl *ASD) {
assert(!InsideAbstractStorageDecl &&
"unexpected nesting of abstract storage decls");
InsideAbstractStorageDecl = true;
visitMembers(ASD);
InsideAbstractStorageDecl = false;
}
void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
if (isPrivateDecl(VD))
return;

// statically/globally stored variables have some special handling.
if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
// The actual variable has a symbol.
Mangle::ASTMangler mangler;
addSymbol(mangler.mangleEntity(VD, false));

// Variables in the main file don't get accessors, despite otherwise looking
// like globals.
if (!FileHasEntryPoint)
// Top-level variables (*not* statics) in the main file don't get accessors,
// despite otherwise looking like globals.
if (!FileHasEntryPoint || VD->isStatic())
addSymbol(SILDeclRef(VD, SILDeclRef::Kind::GlobalAccessor));

// In this case, the members of the VarDecl don't also appear as top-level
// decls, so we need to explicitly walk them.
visitMembers(VD);
}

visitAbstractStorageDecl(VD);
}

void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
Expand Down
4 changes: 2 additions & 2 deletions test/SILGen/constrained_extensions.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -emit-silgen -primary-file %s | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -O -primary-file %s
// RUN: %target-swift-frontend -emit-ir -primary-file %s
// RUN: %target-swift-frontend -emit-sil -O -primary-file %s > /dev/null
// RUN: %target-swift-frontend -emit-ir -primary-file %s > /dev/null

extension Array where Element == Int {
// CHECK-LABEL: sil @_T0Sa22constrained_extensionsSiRszlESaySiGyt1x_tcfC : $@convention(method) (@thin Array<Int>.Type) -> @owned Array<Int>
Expand Down
2 changes: 1 addition & 1 deletion test/TBD/global.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s

public let publicLet: Int = 0
internal let internalLet: Int = 0
Expand Down
2 changes: 1 addition & 1 deletion test/TBD/protocol.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s

public protocol Public {
func publicMethod()
Expand Down
2 changes: 1 addition & 1 deletion test/TBD/struct.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s

public struct PublicNothing {}

Expand Down