mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[AST] Move getEffectiveAccess calls into SIL.
This commit is contained in:
@@ -398,13 +398,6 @@ public:
|
||||
return ContextAndInvalid.getPointer().dyn_cast<AbstractStorageDecl *>();
|
||||
}
|
||||
|
||||
bool isSerialized() const {
|
||||
auto *nominal = getType()->getAnyNominal();
|
||||
return nominal->hasFixedLayout() &&
|
||||
getProtocol()->getEffectiveAccess() >= Accessibility::Public &&
|
||||
nominal->getEffectiveAccess() >= Accessibility::Public;
|
||||
}
|
||||
|
||||
/// Retrieve the type witness and type decl (if one exists)
|
||||
/// for the given associated type.
|
||||
std::pair<Type, TypeDecl *>
|
||||
|
||||
@@ -34,8 +34,10 @@ namespace swift {
|
||||
|
||||
class SILFunction;
|
||||
class SILModule;
|
||||
class ProtocolConformance;
|
||||
class NormalProtocolConformance;
|
||||
enum IsSerialized_t : unsigned char;
|
||||
enum class ResilienceStrategy : unsigned;
|
||||
|
||||
/// A mapping from each requirement of a protocol to the SIL-level entity
|
||||
/// satisfying the requirement for a concrete type.
|
||||
@@ -269,13 +271,18 @@ public:
|
||||
void convertToDefinition(ArrayRef<Entry> newEntries,
|
||||
IsSerialized_t isSerialized);
|
||||
|
||||
// Whether a conformance should be serialized.
|
||||
static bool conformanceIsSerialized(ProtocolConformance *conformance,
|
||||
ResilienceStrategy strategy,
|
||||
bool silSerializeWitnessTables);
|
||||
|
||||
/// Print the witness table.
|
||||
void print(llvm::raw_ostream &OS, bool Verbose = false) const;
|
||||
|
||||
/// Dump the witness table to stderr.
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
|
||||
} // end swift namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace swift {
|
||||
class FileUnit;
|
||||
|
||||
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
|
||||
bool hasMultipleIRGenThreads, bool isWholeModule);
|
||||
bool hasMultipleIRGenThreads, bool isWholeModule,
|
||||
bool silSerializeWitnessTables);
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
@@ -665,8 +665,10 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
}
|
||||
|
||||
if (Action == FrontendOptions::EmitTBD) {
|
||||
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
|
||||
const auto &silOpts = Invocation.getSILOptions();
|
||||
auto hasMultipleIRGenThreads = silOpts.NumThreads > 1;
|
||||
return writeTBD(Instance.getMainModule(), hasMultipleIRGenThreads,
|
||||
silOpts.SILSerializeWitnessTables,
|
||||
opts.getSingleOutputFilename());
|
||||
}
|
||||
|
||||
@@ -942,14 +944,16 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
!astGuaranteedToCorrespondToSIL)
|
||||
break;
|
||||
|
||||
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
|
||||
const auto &silOpts = Invocation.getSILOptions();
|
||||
auto hasMultipleIRGenThreads = silOpts.NumThreads > 1;
|
||||
bool error;
|
||||
if (PrimarySourceFile)
|
||||
error = validateTBD(PrimarySourceFile, *IRModule, hasMultipleIRGenThreads,
|
||||
allSymbols);
|
||||
silOpts.SILSerializeWitnessTables, allSymbols);
|
||||
else
|
||||
error = validateTBD(Instance.getMainModule(), *IRModule,
|
||||
hasMultipleIRGenThreads, allSymbols);
|
||||
hasMultipleIRGenThreads,
|
||||
silOpts.SILSerializeWitnessTables, allSymbols);
|
||||
if (error)
|
||||
return true;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ static std::vector<StringRef> sortSymbols(llvm::StringSet<> &symbols) {
|
||||
}
|
||||
|
||||
bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
|
||||
StringRef OutputFilename) {
|
||||
bool silSerializeWitnessTables, StringRef OutputFilename) {
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
|
||||
if (EC) {
|
||||
@@ -50,7 +50,7 @@ bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
|
||||
llvm::StringSet<> symbols;
|
||||
for (auto file : M->getFiles())
|
||||
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
|
||||
/*isWholeModule=*/true);
|
||||
/*isWholeModule=*/true, silSerializeWitnessTables);
|
||||
|
||||
// Ensure the order is stable.
|
||||
for (auto &symbol : sortSymbols(symbols)) {
|
||||
@@ -125,11 +125,12 @@ static bool validateSymbolSet(DiagnosticEngine &diags,
|
||||
|
||||
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
|
||||
bool hasMultipleIRGenThreads,
|
||||
bool silSerializeWitnessTables,
|
||||
bool diagnoseExtraSymbolsInTBD) {
|
||||
llvm::StringSet<> symbols;
|
||||
for (auto file : M->getFiles())
|
||||
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
|
||||
/*isWholeModule=*/true);
|
||||
/*isWholeModule=*/true, silSerializeWitnessTables);
|
||||
|
||||
return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
|
||||
diagnoseExtraSymbolsInTBD);
|
||||
@@ -137,10 +138,11 @@ bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
|
||||
|
||||
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
|
||||
bool hasMultipleIRGenThreads,
|
||||
bool silSerializeWitnessTables,
|
||||
bool diagnoseExtraSymbolsInTBD) {
|
||||
llvm::StringSet<> symbols;
|
||||
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
|
||||
/*isWholeModule=*/false);
|
||||
/*isWholeModule=*/false, silSerializeWitnessTables);
|
||||
|
||||
return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
|
||||
symbols, IRModule, diagnoseExtraSymbolsInTBD);
|
||||
|
||||
@@ -25,12 +25,14 @@ class FileUnit;
|
||||
class FrontendOptions;
|
||||
|
||||
bool writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
|
||||
llvm::StringRef OutputFilename);
|
||||
bool silSerializeWitnessTables, llvm::StringRef OutputFilename);
|
||||
bool inputFileKindCanHaveTBDValidated(InputFileKind kind);
|
||||
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule,
|
||||
bool hasMultipleIRGenThreads, bool diagnoseExtraSymbolsInTBD);
|
||||
bool hasMultipleIRGenThreads, bool silSerializeWitnessTables,
|
||||
bool diagnoseExtraSymbolsInTBD);
|
||||
bool validateTBD(FileUnit *M, llvm::Module &IRModule,
|
||||
bool hasMultipleIRGenThreads, bool diagnoseExtraSymbolsInTBD);
|
||||
bool hasMultipleIRGenThreads, bool silSerializeWitnessTables,
|
||||
bool diagnoseExtraSymbolsInTBD);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "swift/SIL/SILWitnessTable.h"
|
||||
#include "swift/AST/ASTMangler.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/AST/ProtocolConformance.h"
|
||||
#include "swift/SIL/SILModule.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
@@ -155,3 +156,18 @@ void SILWitnessTable::convertToDefinition(ArrayRef<Entry> entries,
|
||||
Identifier SILWitnessTable::getIdentifier() const {
|
||||
return Mod.getASTContext().getIdentifier(Name);
|
||||
}
|
||||
|
||||
bool SILWitnessTable::conformanceIsSerialized(ProtocolConformance *conformance,
|
||||
ResilienceStrategy strategy,
|
||||
bool silSerializeWitnessTables) {
|
||||
auto *nominal = conformance->getType()->getAnyNominal();
|
||||
// Only serialize if the witness table is sufficiently static, andresilience
|
||||
// is explicitly enabled for this compilation or if we serialize all eligible
|
||||
// witness tables.
|
||||
return (strategy == ResilienceStrategy::Resilient ||
|
||||
silSerializeWitnessTables) &&
|
||||
nominal->hasFixedLayout() &&
|
||||
conformance->getProtocol()->getEffectiveAccess() >=
|
||||
Accessibility::Public &&
|
||||
nominal->getEffectiveAccess() >= Accessibility::Public;
|
||||
}
|
||||
|
||||
@@ -314,17 +314,14 @@ public:
|
||||
Serialized = IsNotSerialized;
|
||||
|
||||
// Serialize the witness table if we're serializing everything with
|
||||
// -sil-serialize-all.
|
||||
// -sil-serialize-all....
|
||||
if (SGM.isMakeModuleFragile())
|
||||
Serialized = IsSerialized;
|
||||
|
||||
// Serialize the witness table if the conformance itself thinks it should be
|
||||
// and resilience is explicitly enabled for this compilaiton or if we serialize
|
||||
// all eligible witness tables.
|
||||
if ((SGM.M.getSwiftModule()->getResilienceStrategy() ==
|
||||
ResilienceStrategy::Resilient ||
|
||||
SGM.M.getOptions().SILSerializeWitnessTables) &&
|
||||
Conformance->isSerialized())
|
||||
// ... or if the conformance itself thinks it should be.
|
||||
if (SILWitnessTable::conformanceIsSerialized(
|
||||
Conformance, SGM.M.getSwiftModule()->getResilienceStrategy(),
|
||||
SGM.M.getOptions().SILSerializeWitnessTables))
|
||||
Serialized = IsSerialized;
|
||||
|
||||
// Not all protocols use witness tables; in this case we just skip
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "swift/IRGen/Linking.h"
|
||||
#include "swift/SIL/FormalLinkage.h"
|
||||
#include "swift/SIL/SILDeclRef.h"
|
||||
#include "swift/SIL/SILWitnessTable.h"
|
||||
#include "swift/SIL/TypeLowering.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
|
||||
@@ -41,6 +42,7 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
|
||||
const UniversalLinkageInfo &UniversalLinkInfo;
|
||||
ModuleDecl *SwiftModule;
|
||||
bool FileHasEntryPoint;
|
||||
bool SILSerializeWitnessTables;
|
||||
|
||||
void addSymbol(StringRef name) {
|
||||
auto isNewValue = Symbols.insert(name).second;
|
||||
@@ -67,9 +69,11 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
|
||||
public:
|
||||
TBDGenVisitor(StringSet &symbols,
|
||||
const UniversalLinkageInfo &universalLinkInfo,
|
||||
ModuleDecl *swiftModule, bool fileHasEntryPoint)
|
||||
ModuleDecl *swiftModule, bool fileHasEntryPoint,
|
||||
bool silSerializeWitnessTables)
|
||||
: Symbols(symbols), UniversalLinkInfo(universalLinkInfo),
|
||||
SwiftModule(swiftModule), FileHasEntryPoint(fileHasEntryPoint) {}
|
||||
SwiftModule(swiftModule), FileHasEntryPoint(fileHasEntryPoint),
|
||||
SILSerializeWitnessTables(silSerializeWitnessTables) {}
|
||||
|
||||
void visitMembers(Decl *D) {
|
||||
SmallVector<Decl *, 4> members;
|
||||
@@ -190,10 +194,12 @@ void TBDGenVisitor::addConformances(DeclContext *DC) {
|
||||
// FIXME: the logic around visibility in extensions is confusing, and
|
||||
// sometimes witness thunks need to be manually made public.
|
||||
|
||||
auto conformanceIsSerialized = normalConformance->isSerialized();
|
||||
auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
|
||||
normalConformance, SwiftModule->getResilienceStrategy(),
|
||||
SILSerializeWitnessTables);
|
||||
auto addSymbolIfNecessary = [&](ValueDecl *valueReq,
|
||||
SILLinkage witnessLinkage) {
|
||||
if (conformanceIsSerialized &&
|
||||
if (conformanceIsFixed &&
|
||||
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
|
||||
Mangle::ASTMangler Mangler;
|
||||
addSymbol(Mangler.mangleWitnessThunk(normalConformance, valueReq));
|
||||
@@ -390,7 +396,8 @@ void TBDGenVisitor::visitProtocolDecl(ProtocolDecl *PD) {
|
||||
|
||||
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
|
||||
bool hasMultipleIRGenThreads,
|
||||
bool isWholeModule) {
|
||||
bool isWholeModule,
|
||||
bool silSerializeWitnessTables) {
|
||||
UniversalLinkageInfo linkInfo(file->getASTContext().LangOpts.Target,
|
||||
hasMultipleIRGenThreads, isWholeModule);
|
||||
|
||||
@@ -400,7 +407,7 @@ void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
|
||||
auto hasEntryPoint = file->hasEntryPoint();
|
||||
|
||||
TBDGenVisitor visitor(symbols, linkInfo, file->getParentModule(),
|
||||
hasEntryPoint);
|
||||
hasEntryPoint, silSerializeWitnessTables);
|
||||
for (auto d : decls)
|
||||
visitor.visit(d);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user