Skip to content

SILDebugScopes: Don't ignore ConditionalClauseInitializerScope. #66692

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 17, 2023
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
1 change: 0 additions & 1 deletion include/swift/AST/ASTScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,6 @@ class ConditionalClauseInitializerScope final : public ASTScopeImpl {
SourceRange
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
std::string getClassName() const override;
bool ignoreInDebugInfo() const override { return true; }

private:
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
Expand Down
72 changes: 43 additions & 29 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,52 @@ SILGenFunction::SILGenFunction(SILGenModule &SGM, SILFunction &F,
assert(DC && "creating SGF without a DeclContext?");
B.setInsertionPoint(createBasicBlock());
B.setCurrentDebugScope(F.getDebugScope());

// Populate VarDeclScopeMap.
SourceLoc SLoc = F.getLocation().getSourceLoc();
if (SF && SLoc) {
FnASTScope = ast_scope::ASTScopeImpl::findStartingScopeForLookup(SF, SLoc);
ScopeMap.insert({{FnASTScope, nullptr}, F.getDebugScope()});

// Collect all variable declarations in this scope.
struct Consumer : public namelookup::AbstractASTScopeDeclConsumer {
const ast_scope::ASTScopeImpl *ASTScope;
VarDeclScopeMapTy &VarDeclScopeMap;
Consumer(const ast_scope::ASTScopeImpl *ASTScope,
VarDeclScopeMapTy &VarDeclScopeMap)
: ASTScope(ASTScope), VarDeclScopeMap(VarDeclScopeMap) {}

bool consume(ArrayRef<ValueDecl *> values,
NullablePtr<DeclContext> baseDC) override {
LLVM_DEBUG(ASTScope->print(llvm::errs(), 0, false, false));
for (auto &value : values) {
LLVM_DEBUG({
if (value->hasName())
llvm::dbgs() << "+ " << value->getBaseIdentifier() << "\n";
});

// FIXME: ASTs coming out of the autodiff transformation trigger this.
// assert((VarDeclScopeMap.count(value) == 0 ||
// VarDeclScopeMap[value] == ASTScope) &&
// "VarDecl appears twice");
VarDeclScopeMap.insert({value, ASTScope});
}
return false;
}
bool lookInMembers(const DeclContext *) const override { return false; }
#ifndef NDEBUG
void startingNextLookupStep() override {}
void finishingLookup(std::string) const override {}
bool isTargetLookup() const override { return false; }
#endif
};
const_cast<ast_scope::ASTScopeImpl *>(FnASTScope)
->preOrderChildrenDo([&](ast_scope::ASTScopeImpl *ASTScope) {
if (!ASTScope->ignoreInDebugInfo()) {
Consumer consumer(ASTScope, VarDeclScopeMap);
ASTScope->lookupLocalsOrMembers(consumer);
}
});
}
}

Expand Down Expand Up @@ -202,8 +244,6 @@ const SILDebugScope *SILGenFunction::getScopeOrNull(SILLocation Loc,
SourceLoc SLoc = Loc.getSourceLoc();
if (!SF || LastSourceLoc == SLoc)
return nullptr;
// Prime VarDeclScopeMap.
auto Scope = getOrCreateScope(SLoc);
if (ForMetaInstruction)
if (ValueDecl *ValDecl = Loc.getAsASTNode<ValueDecl>()) {
// The source location of a VarDecl isn't necessarily in the same scope
Expand All @@ -212,7 +252,7 @@ const SILDebugScope *SILGenFunction::getScopeOrNull(SILLocation Loc,
if (ValueScope != VarDeclScopeMap.end())
return getOrCreateScope(ValueScope->second, F.getDebugScope());
}
return Scope;
return getOrCreateScope(SLoc);
}

const SILDebugScope *SILGenFunction::getOrCreateScope(SourceLoc SLoc) {
Expand Down Expand Up @@ -406,32 +446,6 @@ SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope,
return ParentScope->InlinedCallSite != InlinedAt ? FnScope : ParentScope;
}

// Collect all variable declarations in this scope.
struct Consumer : public namelookup::AbstractASTScopeDeclConsumer {
const ast_scope::ASTScopeImpl *ASTScope;
VarDeclScopeMapTy &VarDeclScopeMap;
Consumer(const ast_scope::ASTScopeImpl *ASTScope,
VarDeclScopeMapTy &VarDeclScopeMap)
: ASTScope(ASTScope), VarDeclScopeMap(VarDeclScopeMap) {}

bool consume(ArrayRef<ValueDecl *> values,
NullablePtr<DeclContext> baseDC) override {
for (auto &value : values) {
assert(VarDeclScopeMap.count(value) == 0 && "VarDecl appears twice");
VarDeclScopeMap.insert({value, ASTScope});
}
return false;
}
bool lookInMembers(const DeclContext *) const override { return false; }
#ifndef NDEBUG
void startingNextLookupStep() override {}
void finishingLookup(std::string) const override {}
bool isTargetLookup() const override { return false; }
#endif
};
Consumer consumer(ASTScope, VarDeclScopeMap);
ASTScope->lookupLocalsOrMembers(consumer);

// Collapse BraceStmtScopes whose parent is a .*BodyScope.
if (auto Parent = ASTScope->getParent().getPtrOrNull())
if (Parent->getSourceRangeOfThisASTNode() ==
Expand Down
4 changes: 2 additions & 2 deletions test/DebugInfo/case-scope2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ func consume<T>(_ t: T) {}
public func f(_ s1: Set<Int>?, _ s2: Set<Int>?) {
switch (s1, s2) {
case (nil, let a), (let a, nil):
// CHECK: debug_value {{.*}} $Optional<Set<Int>>, let, name "a", {{.*}}:[[@LINE-1]]:18, scope [[S1]]
// CHECK: debug_value {{.*}} $Optional<Set<Int>>, let, name "a", {{.*}}:11:18, scope [[S2]]
consume(a)
case (let a?, _):
// CHECK: debug_value {{.*}} $Set<Int>, let, name "a", {{.*}}:[[@LINE-1]]:13, scope [[S3]]
// CHECK: debug_value {{.*}} $Set<Int>, let, name "a", {{.*}}:14:13, scope [[S3]]
consume((a))
}
}
22 changes: 22 additions & 0 deletions test/DebugInfo/case-scope3.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %target-swift-frontend -module-name a -parse-as-library -emit-sil -g %s | %FileCheck %s

enum E {
case integerValue(Int?)
}

func getE() -> E? { return .integerValue(0) }

func f() -> Int {
if case .integerValue(let nextValue) = getE(), let nextValue = nextValue {
// CHECK: sil_scope [[F:[0-9]+]] { loc "{{.*}}":9:6 parent @$s1a1fSiyF
// CHECK: sil_scope [[S0:[0-9]+]] { loc "{{.*}}":10:5 parent [[F]] }
// CHECK: sil_scope [[S1:[0-9]+]] { loc "{{.*}}":10:44 parent [[S0]] }
// CHECK: sil_scope [[S2:[0-9]+]] { loc "{{.*}}":10:44 parent [[S0]] }
// CHECK: sil_scope [[S3:[0-9]+]] { loc "{{.*}}":10:68 parent [[S2]] }
// CHECK: sil_scope [[S4:[0-9]+]] { loc "{{.*}}":10:78 parent [[S3]] }
// CHECK: debug_value {{.*}}: $Optional<Int>, let, name "nextValue", {{.*}}:10:31, scope [[S2]]
// CHECK: debug_value {{.*}}: $Int, let, name "nextValue", {{.*}}:10:56, scope [[S3]]
return nextValue
}
return 0
}
2 changes: 1 addition & 1 deletion test/DebugInfo/for-scope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public func f(_ xs: [String?]) {
// CHECK: sil_scope [[S5:[0-9]+]] { loc "{{.*}}":7:13 parent [[S4]] }
// CHECK: sil_scope [[S6:[0-9]+]] { loc "{{.*}}":7:9 parent [[S4]] }

// CHECK: debug_value %[[X:.*]] : $Optional<String>, let, name "x", {{.*}}, scope [[S3]]
// CHECK: debug_value %[[X:.*]] : $Optional<String>, let, name "x", {{.*}}, scope [[S4]]
// CHECK: retain_value %[[X]] : $Optional<String>, {{.*}}, scope [[S5]]
// CHECK: debug_value %[[X1:[0-9]+]] : $String, let, name "x", {{.*}}, scope [[S6]]
// CHECK: release_value %[[X1]] : $String, {{.*}}, scope [[S6]]
Expand Down
10 changes: 6 additions & 4 deletions test/DebugInfo/guard-let-scope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ func f(c: AnyObject??) {
// CHECK: sil_scope [[S5:[0-9]+]] { {{.*}} parent [[S3]] }
// CHECK: sil_scope [[S6:[0-9]+]] { loc "{{.*}}":7:3 parent [[S5]] }
// CHECK: sil_scope [[S7:[0-9]+]] { loc "{{.*}}":7:17 parent [[S6]] }
// CHECK: sil_scope [[S8:[0-9]+]] { loc "{{.*}}":7:28 parent [[S7]] }
// CHECK: sil_scope [[S8:[0-9]+]] { loc "{{.*}}":7:17 parent [[S6]] }
// CHECK: sil_scope [[S9:[0-9]+]] { loc "{{.*}}":7:28 parent [[S8]] }
// CHECK: sil_scope [[S10:[0-9]+]] { loc "{{.*}}":7:28 parent [[S8]] }
// CHECK: debug_value %{{.*}} : $Optional<Optional<AnyObject>>, let, name "x"{{.*}} scope [[S5]]
// CHECK: debug_value %{{.*}} : $Optional<AnyObject>, let, name "x", {{.*}} scope [[S7]]
// CHECK: debug_value %{{.*}} : $AnyObject, let, name "x", {{.*}} scope [[S8]]
// CHECK: debug_value %{{.*}} : $Optional<AnyObject>, let, name "x", {{.*}} scope [[S8]]
// CHECK: debug_value %{{.*}} : $AnyObject, let, name "x", {{.*}} scope [[S10]]
fatalError()
}
// CHECK: function_ref {{.*3use.*}} scope [[S8]]
// CHECK: function_ref {{.*3use.*}} scope [[S10]]
use(x)
}
11 changes: 6 additions & 5 deletions test/DebugInfo/guard-let-scope2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ public func f(x: String?) throws {
s = SomeObject()
return s != nil
}
// CHECK: sil_scope [[S1:[0-9]+]] { {{.*}} parent @{{.*}}1f
// CHECK: sil_scope [[S2:[0-9]+]] { {{.*}} parent [[S1]] }
// CHECK: sil_scope [[S3:[0-9]+]] { {{.*}} parent [[S1]] }
// CHECK: sil_scope [[S4:[0-9]+]] { {{.*}} parent [[S2]] }
// CHECK: alloc_stack {{.*}} $SomeObject, let, name "s", {{.*}} scope [[S4]]
// CHECK: sil_scope [[S1:[0-9]+]] { {{.*}}:13:13 parent @{{.*}}1f
// CHECK: sil_scope [[S2:[0-9]+]] { {{.*}}:14:7 parent [[S1]] }
// CHECK: sil_scope [[S3:[0-9]+]] { {{.*}}:14:26 parent [[S1]] }
// CHECK: sil_scope [[S4:[0-9]+]] { {{.*}}:25:3 parent [[S2]] }
// CHECK: sil_scope [[S5:[0-9]+]] { {{.*}}:25:17 parent [[S4]] }
// CHECK: alloc_stack {{.*}} $SomeObject, let, name "s", {{.*}} scope [[S5]]
guard let s = s else {
assert(false)
return
Expand Down
12 changes: 7 additions & 5 deletions test/DebugInfo/guard-let-scope3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ public class S {
private var c = [Int : C?]()
public func f(_ i: Int) throws -> C {
guard let x = c[i], let x else {
// CHECK: sil_scope [[P:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:5
// CHECK: sil_scope [[X1:[0-9]+]] { loc "{{.*}}":[[@LINE-2]]:19 parent [[P]]
// CHECK: sil_scope [[X2:[0-9]+]] { loc "{{.*}}":[[@LINE-3]]:29 parent [[X1]]
// CHECK: sil_scope [[GUARD:[0-9]+]] { loc "{{.*}}":[[@LINE-4]]:36 parent [[P]]
// CHECK: sil_scope [[P:[0-9]+]] { loc "{{.*}}":9:5
// CHECK: sil_scope [[X1_RHS:[0-9]+]] { loc "{{.*}}":9:19 parent [[P]]
// CHECK: sil_scope [[X1:[0-9]+]] { loc "{{.*}}":9:19 parent [[P]]
// CHECK: sil_scope [[X2:[0-9]+]] { loc "{{.*}}":9:29 parent [[X1]]
// CHECK: sil_scope [[GUARD:[0-9]+]] { loc "{{.*}}":9:36 parent [[P]]
// CHECK: debug_value {{.*}} : $Optional<C>, let, name "x", {{.*}}, scope [[X1]]
// CHECK: debug_value {{.*}} : $C, let, name "x", {{.*}}, scope [[X2]]
// CHECK-NEXT: scope [[X2]]
// FIXME: This source location is a little wild.
// CHECK-NEXT: strong_retain{{.*}}:[[@LINE+4]]:12, scope [[X2]]
throw MyError()
// CHECK: function_ref {{.*}}MyError{{.*}}:[[@LINE-1]]:13, scope [[GUARD]]
}
Expand Down
18 changes: 18 additions & 0 deletions test/DebugInfo/guard-let-scope4.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %target-swift-frontend -g -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
open class C {
public func fun() {}

public func run() {
{ [weak self] in
guard let self else { fatalError("cannot happen") }
// CHECK: sil_scope [[LAMBDA:[0-9]+]] { loc "{{.*}}":6:5
// CHECK: sil_scope [[BODY:[0-9]+]] { loc "{{.*}}":6:19 parent [[LAMBDA]]
// CHECK: sil_scope [[LET:[0-9]+]] { loc "{{.*}}":7:7 parent [[BODY]]
// CHECK: sil_scope [[GUARD:[0-9]+]] { loc "{{.*}}":7:17 parent [[LET]]
// CHECK: debug_value {{.*}} : $C, let, name "self", {{.*}}, scope [[GUARD]]
// CHECK: function_ref {{.*}}3fun{{.*}}, scope [[GUARD]]
// CHECK-NEXT: apply {{.*}}, scope [[GUARD]]
self.fun()
}()
}
}
13 changes: 8 additions & 5 deletions test/DebugInfo/if-let-scope.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// RUN: %target-swift-frontend -g -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
func use<T>(_ t: T) {}
public func f(value: String?) {
// CHECK: sil_scope [[S0:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:13
// CHECK: sil_scope [[S0:[0-9]+]] { loc "{{.*}}":3:13
if let value, let value = Int(value) {
// CHECK: sil_scope [[S1:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:10
// CHECK: sil_scope [[S2:[0-9]+]] { loc "{{.*}}":[[@LINE-2]]:29 parent [[S1]] }
// CHECK: sil_scope [[S1:[0-9]+]] { loc "{{.*}}":5:3
// CHECK: sil_scope [[S2:[0-9]+]] { loc "{{.*}}":5:10
// CHECK: sil_scope [[S3:[0-9]+]] { loc "{{.*}}":5:29 parent [[S2]] }
// CHECK: sil_scope [[S4:[0-9]+]] { loc "{{.*}}":5:29 parent [[S2]] }
// CHECK: sil_scope [[S5:[0-9]+]] { loc "{{.*}}":5:40 parent [[S4]] }
// CHECK: debug_value {{.*}} : $Optional<String>, let, name "value", {{.*}}, scope [[S0]]
// CHECK: debug_value {{.*}} : $String, let, name "value", {{.*}}, scope [[S1]]
// CHECK: debug_value {{.*}} : $Int, let, name "value", {{.*}}, scope [[S2]]
// CHECK: debug_value {{.*}} : $String, let, name "value", {{.*}}, scope [[S2]]
// CHECK: debug_value {{.*}} : $Int, let, name "value", {{.*}}, scope [[S4]]
use((value))
}
}
4 changes: 2 additions & 2 deletions test/SILGen/switch-case-debug-descriptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ enum E {
func test1(_ e: E) {
switch e { // SCOPE: sil_scope [[test1_switch:[0-9]+]] {{.*}}:[[@LINE]]:3
case .one(let payload), .two(let payload): // SCOPE-NEXT: sil_scope [[test1_case1:[0-9]+]] {{.*}}:[[@LINE]]:3 parent [[test1_switch]]
print(payload)
print(payload) // SCOPE-NEXT: sil_scope {{.*}}:[[@LINE]]:5 parent [[test1_case1]]
case .three(let payload): // SCOPE-NEXT: sil_scope [[test1_case2:[0-9]+]] {{.*}}:[[@LINE]]:3 parent [[test1_switch]]
print(payload)
}
Expand Down Expand Up @@ -43,7 +43,7 @@ func test4(_ e: E) {
print(x) // SCOPE-NEXT: sil_scope {{.*}}:[[@LINE]]:5 parent [[test4_case1]]
fallthrough
case .two(let x): // SCOPE-NEXT: sil_scope [[test4_case2:[0-9]+]] {{.*}}:[[@LINE]]:3 parent [[test4_switch]]
print(x)
print(x) // SCOPE-NEXT: {{.*}}:[[@LINE]]:5 parent [[test4_case2]]
fallthrough
default: // SCOPE-NEXT: sil_scope [[test4_default:[0-9]+]] {{.*}}:[[@LINE]]:3 parent [[test4_switch]]
print("default") // SCOPE: sil_scope [[test4_default1:[0-9]+]] {{.*}}:[[@LINE]]:5
Expand Down