Skip to content

Commit a24951b

Browse files
author
ematejska
authored
Merge pull request #10482 from huonw/symbol-list-9-4.0
[4.0] More TBD work
2 parents c75dbf9 + 67226a5 commit a24951b

File tree

13 files changed

+191
-64
lines changed

13 files changed

+191
-64
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4097,6 +4097,10 @@ class AbstractStorageDecl : public ValueDecl {
40974097

40984098
FuncDecl *getAccessorFunction(AccessorKind accessor) const;
40994099

4100+
/// \brief Push all of the accessor functions associated with this VarDecl
4101+
/// onto `decls`.
4102+
void getAllAccessorFunctions(SmallVectorImpl<Decl *> &decls) const;
4103+
41004104
/// \brief Turn this into a computed variable, providing a getter and setter.
41014105
void makeComputed(SourceLoc LBraceLoc, FuncDecl *Get, FuncDecl *Set,
41024106
FuncDecl *MaterializeForSet, SourceLoc RBraceLoc);

include/swift/AST/ProtocolConformance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class NormalProtocolConformance : public ProtocolConformance,
392392
AbstractStorageDecl *getBehaviorDecl() const {
393393
return ContextAndInvalid.getPointer().dyn_cast<AbstractStorageDecl *>();
394394
}
395-
395+
396396
/// Retrieve the type witness and type decl (if one exists)
397397
/// for the given associated type.
398398
std::pair<Type, TypeDecl *>

include/swift/SIL/SILLinkage.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,20 @@ inline SILLinkage effectiveLinkageForClassMember(SILLinkage linkage,
252252
return linkage;
253253
}
254254

255+
// FIXME: This should not be necessary, but it looks like visibility rules for
256+
// extension members are slightly bogus, and so some protocol witness thunks
257+
// need to be public.
258+
//
259+
// We allow a 'public' member of an extension to witness a public
260+
// protocol requirement, even if the extended type is not public;
261+
// then SILGen gives the member private linkage, ignoring the more
262+
// visible accessibility it was given in the AST.
263+
inline bool
264+
fixmeWitnessHasLinkageThatNeedsToBePublic(SILLinkage witnessLinkage) {
265+
return !hasPublicVisibility(witnessLinkage) &&
266+
!hasSharedVisibility(witnessLinkage);
267+
}
268+
255269
} // end swift namespace
256270

257271
#endif

include/swift/SIL/SILWitnessTable.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ namespace swift {
3434

3535
class SILFunction;
3636
class SILModule;
37+
class ProtocolConformance;
3738
class NormalProtocolConformance;
3839
enum IsSerialized_t : unsigned char;
40+
enum class ResilienceStrategy : unsigned;
3941

4042
/// A mapping from each requirement of a protocol to the SIL-level entity
4143
/// satisfying the requirement for a concrete type.
@@ -269,13 +271,18 @@ class SILWitnessTable : public llvm::ilist_node<SILWitnessTable>,
269271
void convertToDefinition(ArrayRef<Entry> newEntries,
270272
IsSerialized_t isSerialized);
271273

274+
// Whether a conformance should be serialized.
275+
static bool conformanceIsSerialized(ProtocolConformance *conformance,
276+
ResilienceStrategy strategy,
277+
bool silSerializeWitnessTables);
278+
272279
/// Print the witness table.
273280
void print(llvm::raw_ostream &OS, bool Verbose = false) const;
274281

275282
/// Dump the witness table to stderr.
276283
void dump() const;
277284
};
278-
285+
279286
} // end swift namespace
280287

281288
//===----------------------------------------------------------------------===//

include/swift/TBDGen/TBDGen.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ namespace swift {
1818
class FileUnit;
1919

2020
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
21-
bool hasMultipleIRGenThreads, bool isWholeModule);
21+
bool hasMultipleIRGenThreads, bool isWholeModule,
22+
bool silSerializeWitnessTables);
2223
} // end namespace swift
2324

2425
#endif

lib/AST/Decl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,6 +3430,28 @@ FuncDecl *AbstractStorageDecl::getAccessorFunction(AccessorKind kind) const {
34303430
llvm_unreachable("bad accessor kind!");
34313431
}
34323432

3433+
void AbstractStorageDecl::getAllAccessorFunctions(
3434+
SmallVectorImpl<Decl *> &decls) const {
3435+
auto tryPush = [&](Decl *decl) {
3436+
if (decl)
3437+
decls.push_back(decl);
3438+
};
3439+
3440+
tryPush(getGetter());
3441+
tryPush(getSetter());
3442+
tryPush(getMaterializeForSetFunc());
3443+
3444+
if (hasObservers()) {
3445+
tryPush(getDidSetFunc());
3446+
tryPush(getWillSetFunc());
3447+
}
3448+
3449+
if (hasAddressors()) {
3450+
tryPush(getAddressor());
3451+
tryPush(getMutableAddressor());
3452+
}
3453+
}
3454+
34333455
void AbstractStorageDecl::configureGetSetRecord(GetSetRecord *getSetInfo,
34343456
FuncDecl *getter,
34353457
FuncDecl *setter,

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,10 @@ static bool performCompile(CompilerInstance &Instance,
665665
}
666666

667667
if (Action == FrontendOptions::EmitTBD) {
668-
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
668+
const auto &silOpts = Invocation.getSILOptions();
669+
auto hasMultipleIRGenThreads = silOpts.NumThreads > 1;
669670
return writeTBD(Instance.getMainModule(), hasMultipleIRGenThreads,
671+
silOpts.SILSerializeWitnessTables,
670672
opts.getSingleOutputFilename());
671673
}
672674

@@ -942,14 +944,16 @@ static bool performCompile(CompilerInstance &Instance,
942944
!astGuaranteedToCorrespondToSIL)
943945
break;
944946

945-
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
947+
const auto &silOpts = Invocation.getSILOptions();
948+
auto hasMultipleIRGenThreads = silOpts.NumThreads > 1;
946949
bool error;
947950
if (PrimarySourceFile)
948951
error = validateTBD(PrimarySourceFile, *IRModule, hasMultipleIRGenThreads,
949-
allSymbols);
952+
silOpts.SILSerializeWitnessTables, allSymbols);
950953
else
951954
error = validateTBD(Instance.getMainModule(), *IRModule,
952-
hasMultipleIRGenThreads, allSymbols);
955+
hasMultipleIRGenThreads,
956+
silOpts.SILSerializeWitnessTables, allSymbols);
953957
if (error)
954958
return true;
955959

lib/FrontendTool/TBD.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static std::vector<StringRef> sortSymbols(llvm::StringSet<> &symbols) {
3939
}
4040

4141
bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
42-
StringRef OutputFilename) {
42+
bool silSerializeWitnessTables, StringRef OutputFilename) {
4343
std::error_code EC;
4444
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
4545
if (EC) {
@@ -50,7 +50,7 @@ bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
5050
llvm::StringSet<> symbols;
5151
for (auto file : M->getFiles())
5252
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
53-
/*isWholeModule=*/true);
53+
/*isWholeModule=*/true, silSerializeWitnessTables);
5454

5555
// Ensure the order is stable.
5656
for (auto &symbol : sortSymbols(symbols)) {
@@ -125,22 +125,24 @@ static bool validateSymbolSet(DiagnosticEngine &diags,
125125

126126
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
127127
bool hasMultipleIRGenThreads,
128+
bool silSerializeWitnessTables,
128129
bool diagnoseExtraSymbolsInTBD) {
129130
llvm::StringSet<> symbols;
130131
for (auto file : M->getFiles())
131132
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
132-
/*isWholeModule=*/true);
133+
/*isWholeModule=*/true, silSerializeWitnessTables);
133134

134135
return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
135136
diagnoseExtraSymbolsInTBD);
136137
}
137138

138139
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
139140
bool hasMultipleIRGenThreads,
141+
bool silSerializeWitnessTables,
140142
bool diagnoseExtraSymbolsInTBD) {
141143
llvm::StringSet<> symbols;
142144
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
143-
/*isWholeModule=*/false);
145+
/*isWholeModule=*/false, silSerializeWitnessTables);
144146

145147
return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
146148
symbols, IRModule, diagnoseExtraSymbolsInTBD);

lib/FrontendTool/TBD.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ class FileUnit;
2525
class FrontendOptions;
2626

2727
bool writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
28-
llvm::StringRef OutputFilename);
28+
bool silSerializeWitnessTables, llvm::StringRef OutputFilename);
2929
bool inputFileKindCanHaveTBDValidated(InputFileKind kind);
3030
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule,
31-
bool hasMultipleIRGenThreads, bool diagnoseExtraSymbolsInTBD);
31+
bool hasMultipleIRGenThreads, bool silSerializeWitnessTables,
32+
bool diagnoseExtraSymbolsInTBD);
3233
bool validateTBD(FileUnit *M, llvm::Module &IRModule,
33-
bool hasMultipleIRGenThreads, bool diagnoseExtraSymbolsInTBD);
34+
bool hasMultipleIRGenThreads, bool silSerializeWitnessTables,
35+
bool diagnoseExtraSymbolsInTBD);
3436
}
3537

3638
#endif

lib/SIL/SILWitnessTable.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "swift/SIL/SILWitnessTable.h"
2323
#include "swift/AST/ASTMangler.h"
24+
#include "swift/AST/Module.h"
2425
#include "swift/AST/ProtocolConformance.h"
2526
#include "swift/SIL/SILModule.h"
2627
#include "llvm/ADT/SmallString.h"
@@ -155,3 +156,18 @@ void SILWitnessTable::convertToDefinition(ArrayRef<Entry> entries,
155156
Identifier SILWitnessTable::getIdentifier() const {
156157
return Mod.getASTContext().getIdentifier(Name);
157158
}
159+
160+
bool SILWitnessTable::conformanceIsSerialized(ProtocolConformance *conformance,
161+
ResilienceStrategy strategy,
162+
bool silSerializeWitnessTables) {
163+
auto *nominal = conformance->getType()->getAnyNominal();
164+
// Only serialize if the witness table is sufficiently static, and resilience
165+
// is explicitly enabled for this compilation or if we serialize all eligible
166+
// witness tables.
167+
auto moduleIsResilient = strategy == ResilienceStrategy::Resilient;
168+
auto protocolIsPublic =
169+
conformance->getProtocol()->getEffectiveAccess() >= Accessibility::Public;
170+
auto typeIsPublic = nominal->getEffectiveAccess() >= Accessibility::Public;
171+
return (moduleIsResilient || silSerializeWitnessTables) &&
172+
nominal->hasFixedLayout() && protocolIsPublic && typeIsPublic;
173+
}

lib/SILGen/SILGenType.cpp

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -314,20 +314,14 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
314314
Serialized = IsNotSerialized;
315315

316316
// Serialize the witness table if we're serializing everything with
317-
// -sil-serialize-all.
317+
// -sil-serialize-all...
318318
if (SGM.isMakeModuleFragile())
319319
Serialized = IsSerialized;
320320

321-
auto *nominal = Conformance->getType()->getAnyNominal();
322-
// Serialize the witness table if the conformance itself thinks it should be
323-
// and resilience is explicitly enabled for this compilaiton or if we serialize
324-
// all eligible witness tables.
325-
if ((SGM.M.getSwiftModule()->getResilienceStrategy() ==
326-
ResilienceStrategy::Resilient ||
327-
SGM.M.getOptions().SILSerializeWitnessTables) &&
328-
nominal->hasFixedLayout() &&
329-
proto->getEffectiveAccess() >= Accessibility::Public &&
330-
nominal->getEffectiveAccess() >= Accessibility::Public)
321+
// ... or if the conformance itself thinks it should be.
322+
if (SILWitnessTable::conformanceIsSerialized(
323+
Conformance, SGM.M.getSwiftModule()->getResilienceStrategy(),
324+
SGM.M.getOptions().SILSerializeWitnessTables))
331325
Serialized = IsSerialized;
332326

333327
// Not all protocols use witness tables; in this case we just skip
@@ -427,15 +421,7 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
427421
auto witnessLinkage = witnessRef.getLinkage(ForDefinition);
428422
auto witnessSerialized = Serialized;
429423
if (witnessSerialized &&
430-
!hasPublicVisibility(witnessLinkage) &&
431-
!hasSharedVisibility(witnessLinkage)) {
432-
// FIXME: This should not happen, but it looks like visibility rules
433-
// for extension members are slightly bogus.
434-
//
435-
// We allow a 'public' member of an extension to witness a public
436-
// protocol requirement, even if the extended type is not public;
437-
// then SILGen gives the member private linkage, ignoring the more
438-
// visible accessibility it was given in the AST.
424+
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
439425
witnessLinkage = SILLinkage::Public;
440426
witnessSerialized = (SGM.isMakeModuleFragile()
441427
? IsSerialized

0 commit comments

Comments
 (0)