mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Eagerly emit getters at Onone.
Force SILGen to also eagerly emit getters when compiling at Onone. The reason for this is that getters (even not user-written ones, generated by result builders) can, and are often called by users debugging swift programs, and should be available for that reason. rdar://133329303
This commit is contained in:
@@ -576,6 +576,10 @@ struct SILDeclRef {
|
||||
/// for e.g a lazy variable getter.
|
||||
bool hasUserWrittenCode() const;
|
||||
|
||||
/// Returns true if this is a function that should be emitted because it is
|
||||
/// accessible in the debugger.
|
||||
bool shouldBeEmittedForDebugger() const;
|
||||
|
||||
/// Return the scope in which the parent class of a method (i.e. class
|
||||
/// containing this declaration) can be subclassed, returning NotApplicable if
|
||||
/// this is not a method, there is no such class, or the class cannot be
|
||||
|
||||
@@ -387,6 +387,39 @@ bool SILDeclRef::hasUserWrittenCode() const {
|
||||
llvm_unreachable("Unhandled case in switch!");
|
||||
}
|
||||
|
||||
bool SILDeclRef::shouldBeEmittedForDebugger() const {
|
||||
if (!isFunc())
|
||||
return false;
|
||||
|
||||
if (getASTContext().SILOpts.OptMode != OptimizationMode::NoOptimization)
|
||||
return false;;
|
||||
|
||||
if (!getASTContext().SILOpts.ShouldFunctionsBePreservedToDebugger)
|
||||
return false;
|
||||
|
||||
if (getASTContext().LangOpts.hasFeature(Feature::Embedded))
|
||||
return false;
|
||||
|
||||
ValueDecl *decl = getDecl();
|
||||
DeclAttributes &attrs = decl->getAttrs();
|
||||
if (attrs.hasSemanticsAttr("no.preserve.debugger"))
|
||||
return false;
|
||||
|
||||
if (getLinkage(ForDefinition) == SILLinkage::Shared)
|
||||
return false;
|
||||
|
||||
if (auto decl = getDecl())
|
||||
if (!decl->isImplicit())
|
||||
return true;
|
||||
|
||||
// Synthesized getters are still callable in the debugger.
|
||||
if (auto *accessor = dyn_cast_or_null<AccessorDecl>(getFuncDecl())) {
|
||||
return accessor->isSynthesized() && accessor->isGetterOrSetter();
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum class LinkageLimit {
|
||||
/// No limit.
|
||||
|
||||
@@ -1198,8 +1198,9 @@ void SILGenModule::emitOrDelayFunction(SILDeclRef constant) {
|
||||
auto emitAfter = lastEmittedFunction;
|
||||
|
||||
// Implicit decls may be delayed if they can't be used externally.
|
||||
auto linkage = constant.getLinkage(ForDefinition);
|
||||
bool mayDelay = !constant.hasUserWrittenCode() &&
|
||||
auto linkage = constant.getLinkage(ForDefinition);;
|
||||
bool mayDelay = !constant.shouldBeEmittedForDebugger() &&
|
||||
!constant.hasUserWrittenCode() &&
|
||||
!constant.isDynamicallyReplaceable() &&
|
||||
!isPossiblyUsedExternally(linkage, M.isWholeModule());
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ class Baz: Foo {
|
||||
|
||||
struct Qux {
|
||||
@Bar(wrappedValue: Baz()) private var baz: Baz
|
||||
// Baz instance that is never accessed.
|
||||
@Bar(wrappedValue: Baz()) private var baz2: Baz
|
||||
|
||||
func f() {
|
||||
print(self.baz) // break here
|
||||
@@ -64,3 +66,4 @@ let qux = Qux()
|
||||
qux.f()
|
||||
|
||||
// CHECK: !DISubprogram(name: "baz.get"
|
||||
// CHECK: !DISubprogram(name: "baz2.get"
|
||||
|
||||
Reference in New Issue
Block a user