Skip to content

Commit 6bd4e3b

Browse files
author
Harlan
authored
Merge pull request #19284 from harlanhaskins/i-have-picked-the-cherries-that-were-on-the-tree-and-which-you-were-probably-saving-for-breakfast
[swift-5.0-branch] Cherry pick TBDGen changes
2 parents 7c66d3c + 1b1f25d commit 6bd4e3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+7006
-265
lines changed

include/swift/AST/Decl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4275,6 +4275,13 @@ class AbstractStorageDecl : public ValueDecl {
42754275
return {};
42764276
}
42774277

4278+
/// Visit all the opaque accessors that this storage is expected to have.
4279+
void visitExpectedOpaqueAccessors(
4280+
llvm::function_ref<void (AccessorKind)>) const;
4281+
4282+
/// Visit all the opaque accessors of this storage declaration.
4283+
void visitOpaqueAccessors(llvm::function_ref<void (AccessorDecl*)>) const;
4284+
42784285
void setAccessors(StorageImplInfo storageImpl,
42794286
SourceLoc lbraceLoc, ArrayRef<AccessorDecl*> accessors,
42804287
SourceLoc rbraceLoc);
@@ -4296,6 +4303,9 @@ class AbstractStorageDecl : public ValueDecl {
42964303
/// \brief Add a synthesized materializeForSet accessor.
42974304
void setSynthesizedMaterializeForSet(AccessorDecl *materializeForSet);
42984305

4306+
/// Does this storage require a materializeForSet accessor?
4307+
bool requiresMaterializeForSet() const;
4308+
42994309
SourceRange getBracesRange() const {
43004310
if (auto info = Accessors.getPointer())
43014311
return info->getBracesRange();
@@ -4556,6 +4566,9 @@ class VarDecl : public AbstractStorageDecl {
45564566
ParentPattern = S;
45574567
}
45584568

4569+
/// True if the global stored property requires lazy initialization.
4570+
bool isLazilyInitializedGlobal() const;
4571+
45594572
/// Return the initializer involved in this VarDecl. Recall that the
45604573
/// initializer may be involved in initializing more than just this one
45614574
/// vardecl though. For example, if this is a VarDecl for "x", the pattern

include/swift/Frontend/Frontend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "swift/Sema/SourceLoader.h"
3939
#include "swift/Serialization/Validation.h"
4040
#include "swift/Subsystems.h"
41+
#include "swift/TBDGen/TBDGen.h"
4142
#include "llvm/ADT/IntrusiveRefCntPtr.h"
4243
#include "llvm/ADT/SetVector.h"
4344
#include "llvm/Option/ArgList.h"
@@ -69,6 +70,7 @@ class CompilerInvocation {
6970
MigratorOptions MigratorOpts;
7071
SILOptions SILOpts;
7172
IRGenOptions IRGenOpts;
73+
TBDGenOptions TBDGenOpts;
7274
/// The \c SyntaxParsingCache to use when parsing the main file of this
7375
/// invocation
7476
SyntaxParsingCache *MainFileSyntaxParsingCache = nullptr;
@@ -196,6 +198,9 @@ class CompilerInvocation {
196198
FrontendOptions &getFrontendOptions() { return FrontendOpts; }
197199
const FrontendOptions &getFrontendOptions() const { return FrontendOpts; }
198200

201+
TBDGenOptions &getTBDGenOptions() { return TBDGenOpts; }
202+
const TBDGenOptions &getTBDGenOptions() const { return TBDGenOpts; }
203+
199204
ClangImporterOptions &getClangImporterOptions() { return ClangImporterOpts; }
200205
const ClangImporterOptions &getClangImporterOptions() const {
201206
return ClangImporterOpts;

include/swift/Frontend/FrontendOptions.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef SWIFT_FRONTEND_FRONTENDOPTIONS_H
1414
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
1515

16+
#include "swift/Basic/Version.h"
17+
#include "swift/Frontend/FileTypes.h"
1618
#include "swift/Frontend/FrontendInputsAndOutputs.h"
1719
#include "swift/Frontend/InputFile.h"
1820
#include "llvm/ADT/Hashing.h"
@@ -258,9 +260,6 @@ class FrontendOptions {
258260
/// Compare the symbols in the IR against the TBD file we would generate.
259261
TBDValidationMode ValidateTBDAgainstIR = TBDValidationMode::Default;
260262

261-
/// The install_name to use in the TBD file.
262-
std::string TBDInstallName;
263-
264263
/// An enum with different modes for automatically crashing at defined times.
265264
enum class DebugCrashMode {
266265
None, ///< Don't automatically crash.

include/swift/Option/FrontendOptions.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ def tbd_install_name
7070
def tbd_install_name_EQ : Joined<["-"], "tbd-install_name=">,
7171
Alias<tbd_install_name>;
7272

73+
def tbd_current_version
74+
: Separate<["-"], "tbd-current-version">, MetaVarName<"<version>">,
75+
HelpText<"The current_version to use in an emitted TBD file">;
76+
77+
def tbd_current_version_EQ : Joined<["-"], "tbd-current-version=">,
78+
Alias<tbd_current_version>;
79+
80+
def tbd_compatibility_version
81+
: Separate<["-"], "tbd-compatibility-version">, MetaVarName<"<version>">,
82+
HelpText<"The compatibility_version to use in an emitted TBD file">;
83+
84+
def tbd_compatibility_version_EQ : Joined<["-"], "tbd-compatibility-version=">,
85+
Alias<tbd_compatibility_version>;
86+
7387
def verify : Flag<["-"], "verify">,
7488
HelpText<"Verify diagnostics against expected-{error|warning|note} "
7589
"annotations">;

include/swift/SIL/SILWitnessVisitor.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,9 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
133133
}
134134

135135
void visitAbstractStorageDecl(AbstractStorageDecl *sd) {
136-
asDerived().addMethod(SILDeclRef(sd->getGetter(),
137-
SILDeclRef::Kind::Func));
138-
if (sd->isSettable(sd->getDeclContext())) {
139-
asDerived().addMethod(SILDeclRef(sd->getSetter(),
140-
SILDeclRef::Kind::Func));
141-
if (sd->getMaterializeForSetFunc())
142-
asDerived().addMethod(SILDeclRef(sd->getMaterializeForSetFunc(),
143-
SILDeclRef::Kind::Func));
144-
}
136+
sd->visitOpaqueAccessors([&](AccessorDecl *accessor) {
137+
asDerived().addMethod(SILDeclRef(accessor, SILDeclRef::Kind::Func));
138+
});
145139
}
146140

147141
void visitConstructorDecl(ConstructorDecl *cd) {

include/swift/TBDGen/TBDGen.h

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "llvm/ADT/StringRef.h"
1616
#include "llvm/ADT/StringSet.h"
17+
#include "swift/Basic/Version.h"
1718

1819
namespace llvm {
1920
class raw_ostream;
@@ -23,23 +24,39 @@ namespace swift {
2324
class FileUnit;
2425
class ModuleDecl;
2526

26-
/// \brief Options for controlling the exact set of symbols included in the TBD
27+
/// The current ABI version of Swift, as tapi labels it.
28+
const uint8_t TAPI_SWIFT_ABI_VERSION = 5;
29+
30+
/// Options for controlling the exact set of symbols included in the TBD
2731
/// output.
2832
struct TBDGenOptions {
29-
/// \brief Whether this compilation has multiple IRGen instances.
33+
/// Whether this compilation has multiple IRGen instances.
3034
bool HasMultipleIGMs;
31-
/// \brief The install-name used for the compilation.
32-
llvm::StringRef InstallName;
33-
/// \brief The module link name (for force loading).
34-
llvm::StringRef ModuleLinkName;
35+
36+
/// The install_name to use in the TBD file.
37+
std::string InstallName;
38+
39+
/// The module link name (for force loading).
40+
std::string ModuleLinkName;
41+
42+
/// The current project version to use in the generated TBD file. Defaults
43+
/// to 1, which matches the default if the DYLIB_CURRENT_VERSION build setting
44+
/// is not set.
45+
version::Version CurrentVersion = {1, 0, 0};
46+
47+
/// The dylib compatibility-version to use in the generated TBD file. Defaults
48+
/// to 1, which matches the default if the DYLIB_COMPATIBILITY_VERSION build
49+
/// setting is not set.
50+
version::Version CompatibilityVersion = {1, 0, 0};
3551
};
3652

3753
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
38-
TBDGenOptions &opts);
54+
const TBDGenOptions &opts);
3955
void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
40-
TBDGenOptions &opts);
56+
const TBDGenOptions &opts);
4157

42-
void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, TBDGenOptions &opts);
58+
void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
59+
const TBDGenOptions &opts);
4360

4461
} // end namespace swift
4562

lib/AST/Decl.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,56 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
16001600
llvm_unreachable("bad access semantics");
16011601
}
16021602

1603+
bool AbstractStorageDecl::requiresMaterializeForSet() const {
1604+
// Only for mutable storage.
1605+
if (!supportsMutation())
1606+
return false;
1607+
1608+
// We only need materializeForSet in type contexts.
1609+
// TODO: resilient global variables?
1610+
auto *dc = getDeclContext();
1611+
if (!dc->isTypeContext())
1612+
return false;
1613+
1614+
// Requirements of ObjC protocols don't need materializeForSet.
1615+
if (auto protoDecl = dyn_cast<ProtocolDecl>(dc))
1616+
if (protoDecl->isObjC())
1617+
return false;
1618+
1619+
// Members of structs imported by Clang don't need an eagerly-synthesized
1620+
// materializeForSet.
1621+
if (auto structDecl = dyn_cast<StructDecl>(dc))
1622+
if (structDecl->hasClangNode())
1623+
return false;
1624+
1625+
return true;
1626+
}
1627+
1628+
void AbstractStorageDecl::visitExpectedOpaqueAccessors(
1629+
llvm::function_ref<void (AccessorKind)> visit) const {
1630+
// For now, always assume storage declarations should have getters
1631+
// instead of read accessors.
1632+
visit(AccessorKind::Get);
1633+
1634+
if (supportsMutation()) {
1635+
// All mutable storage should have a setter.
1636+
visit(AccessorKind::Set);
1637+
1638+
// Include materializeForSet if necessary.
1639+
if (requiresMaterializeForSet())
1640+
visit(AccessorKind::MaterializeForSet);
1641+
}
1642+
}
1643+
1644+
void AbstractStorageDecl::visitOpaqueAccessors(
1645+
llvm::function_ref<void (AccessorDecl*)> visit) const {
1646+
visitExpectedOpaqueAccessors([&](AccessorKind kind) {
1647+
auto accessor = getAccessor(kind);
1648+
assert(accessor && "didn't have expected opaque accessor");
1649+
visit(accessor);
1650+
});
1651+
}
1652+
16031653
static bool hasPrivateOrFilePrivateFormalAccess(const ValueDecl *D) {
16041654
return D->hasAccess() && D->getFormalAccess() <= AccessLevel::FilePrivate;
16051655
}
@@ -4263,6 +4313,27 @@ bool VarDecl::isSettable(const DeclContext *UseDC,
42634313
return false;
42644314
}
42654315

4316+
bool VarDecl::isLazilyInitializedGlobal() const {
4317+
assert(!getDeclContext()->isLocalContext() &&
4318+
"not a global variable!");
4319+
assert(hasStorage() && "not a stored global variable!");
4320+
4321+
// Imports from C are never lazily initialized.
4322+
if (hasClangNode())
4323+
return false;
4324+
4325+
if (isDebuggerVar())
4326+
return false;
4327+
4328+
// Top-level global variables in the main source file and in the REPL are not
4329+
// lazily initialized.
4330+
auto sourceFileContext = dyn_cast<SourceFile>(getDeclContext());
4331+
if (!sourceFileContext)
4332+
return true;
4333+
4334+
return !sourceFileContext->isScriptMode();
4335+
}
4336+
42664337
bool SubscriptDecl::isSettable() const {
42674338
return supportsMutation();
42684339
}

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,6 @@ void ArgsToFrontendOptionsConverter::computeTBDOptions() {
214214
A->getOption().getPrefixedName(), value);
215215
}
216216
}
217-
if (const Arg *A = Args.getLastArg(OPT_tbd_install_name)) {
218-
Opts.TBDInstallName = A->getValue();
219-
}
220217
}
221218

222219
void ArgsToFrontendOptionsConverter::setUnsignedIntegerArgument(

lib/Frontend/CompilerInvocation.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,36 @@ void CompilerInvocation::buildDebugFlags(std::string &Output,
752752
}
753753
}
754754

755+
static bool ParseTBDGenArgs(TBDGenOptions &Opts, ArgList &Args,
756+
DiagnosticEngine &Diags,
757+
CompilerInvocation &Invocation) {
758+
using namespace options;
759+
760+
Opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
761+
762+
if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
763+
Opts.ModuleLinkName = A->getValue();
764+
}
765+
766+
if (const Arg *A = Args.getLastArg(OPT_tbd_install_name)) {
767+
Opts.InstallName = A->getValue();
768+
}
769+
770+
if (const Arg *A = Args.getLastArg(OPT_tbd_compatibility_version)) {
771+
if (auto vers = version::Version::parseVersionString(
772+
A->getValue(), SourceLoc(), &Diags)) {
773+
Opts.CompatibilityVersion = *vers;
774+
}
775+
}
776+
if (const Arg *A = Args.getLastArg(OPT_tbd_current_version)) {
777+
if (auto vers = version::Version::parseVersionString(
778+
A->getValue(), SourceLoc(), &Diags)) {
779+
Opts.CurrentVersion = *vers;
780+
}
781+
}
782+
return false;
783+
}
784+
755785
static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
756786
DiagnosticEngine &Diags,
757787
const FrontendOptions &FrontendOpts,
@@ -1110,6 +1140,10 @@ bool CompilerInvocation::parseArgs(
11101140
return true;
11111141
}
11121142

1143+
if (ParseTBDGenArgs(TBDGenOpts, ParsedArgs, Diags, *this)) {
1144+
return true;
1145+
}
1146+
11131147
if (ParseDiagnosticArgs(DiagnosticOpts, ParsedArgs, Diags)) {
11141148
return true;
11151149
}

lib/FrontendTool/FrontendTool.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ static void emitReferenceDependenciesForAllPrimaryInputsIfNeeded(
767767
static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
768768
CompilerInstance &Instance) {
769769
const auto &frontendOpts = Invocation.getFrontendOptions();
770+
const auto &tbdOpts = Invocation.getTBDGenOptions();
770771
if (!frontendOpts.InputsAndOutputs.hasTBDPath())
771772
return false;
772773

@@ -778,16 +779,7 @@ static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
778779

779780
const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
780781

781-
auto installName = frontendOpts.TBDInstallName.empty()
782-
? "lib" + Invocation.getModuleName().str() + ".dylib"
783-
: frontendOpts.TBDInstallName;
784-
785-
TBDGenOptions opts;
786-
opts.InstallName = installName;
787-
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
788-
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
789-
790-
return writeTBD(Instance.getMainModule(), TBDPath, opts);
782+
return writeTBD(Instance.getMainModule(), TBDPath, tbdOpts);
791783
}
792784

793785
static std::deque<PostSILGenInputs>
@@ -972,6 +964,9 @@ static bool performCompile(CompilerInstance &Instance,
972964
return true;
973965
}
974966

967+
if (writeTBDIfNeeded(Invocation, Instance))
968+
return true;
969+
975970
// FIXME: This is still a lousy approximation of whether the module file will
976971
// be externally consumed.
977972
bool moduleIsPublic =
@@ -1196,14 +1191,13 @@ static bool validateTBDIfNeeded(CompilerInvocation &Invocation,
11961191
case FrontendOptions::TBDValidationMode::MissingFromTBD:
11971192
break;
11981193
}
1199-
TBDGenOptions opts;
1200-
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
1201-
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
12021194

12031195
const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
12041196
return MSF.is<SourceFile *>()
1205-
? validateTBD(MSF.get<SourceFile *>(), IRModule, opts, allSymbols)
1206-
: validateTBD(MSF.get<ModuleDecl *>(), IRModule, opts, allSymbols);
1197+
? validateTBD(MSF.get<SourceFile *>(), IRModule,
1198+
Invocation.getTBDGenOptions(), allSymbols)
1199+
: validateTBD(MSF.get<ModuleDecl *>(), IRModule,
1200+
Invocation.getTBDGenOptions(), allSymbols);
12071201
}
12081202

12091203
static bool generateCode(CompilerInvocation &Invocation,

0 commit comments

Comments
 (0)