Skip to content

Commit f9701df

Browse files
Merge pull request #65783 from adrian-prantl/108940570-5.9
Derive the SILDebugScope for a variable declaration from its owning ASTScope.
2 parents 94e1379 + 07b60f1 commit f9701df

13 files changed

+114
-78
lines changed

lib/SILGen/SILGenFunction.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/PropertyWrappers.h"
3333
#include "swift/AST/SourceFile.h"
3434
#include "swift/AST/Types.h"
35+
#include "swift/Basic/Defer.h"
3536
#include "swift/SIL/SILArgument.h"
3637
#include "swift/SIL/SILProfiler.h"
3738
#include "swift/SIL/SILUndef.h"
@@ -201,7 +202,17 @@ const SILDebugScope *SILGenFunction::getScopeOrNull(SILLocation Loc,
201202
SourceLoc SLoc = Loc.getSourceLoc();
202203
if (!SF || LastSourceLoc == SLoc)
203204
return nullptr;
204-
return getOrCreateScope(SLoc);
205+
// Prime VarDeclScopeMap.
206+
auto Scope = getOrCreateScope(SLoc);
207+
if (ForMetaInstruction)
208+
if (ValueDecl *ValDecl = Loc.getAsASTNode<ValueDecl>()) {
209+
// The source location of a VarDecl isn't necessarily in the same scope
210+
// that the variable resides in for name lookup purposes.
211+
auto ValueScope = VarDeclScopeMap.find(ValDecl);
212+
if (ValueScope != VarDeclScopeMap.end())
213+
return getOrCreateScope(ValueScope->second, F.getDebugScope());
214+
}
215+
return Scope;
205216
}
206217

207218
const SILDebugScope *SILGenFunction::getOrCreateScope(SourceLoc SLoc) {
@@ -378,9 +389,14 @@ SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope,
378389
if (It != ScopeMap.end())
379390
return It->second;
380391

381-
LLVM_DEBUG( ASTScope->print(llvm::errs(), 0, false, false) );
392+
LLVM_DEBUG(ASTScope->print(llvm::errs(), 0, false, false));
382393

383-
SILDebugScope *SILScope = nullptr;
394+
auto cache = [&](const SILDebugScope *SILScope) {
395+
ScopeMap.insert({{ASTScope, InlinedAt}, SILScope});
396+
assert(SILScope->getParentFunction() == &F &&
397+
"inlinedAt points to other function");
398+
return SILScope;
399+
};
384400

385401
// Decide whether to pick a parent scope instead.
386402
if (ASTScope->ignoreInDebugInfo()) {
@@ -390,44 +406,68 @@ SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope,
390406
return ParentScope->InlinedCallSite != InlinedAt ? FnScope : ParentScope;
391407
}
392408

409+
// Collect all variable declarations in this scope.
410+
struct Consumer : public namelookup::AbstractASTScopeDeclConsumer {
411+
const ast_scope::ASTScopeImpl *ASTScope;
412+
VarDeclScopeMapTy &VarDeclScopeMap;
413+
Consumer(const ast_scope::ASTScopeImpl *ASTScope,
414+
VarDeclScopeMapTy &VarDeclScopeMap)
415+
: ASTScope(ASTScope), VarDeclScopeMap(VarDeclScopeMap) {}
416+
417+
bool consume(ArrayRef<ValueDecl *> values,
418+
NullablePtr<DeclContext> baseDC) override {
419+
for (auto &value : values) {
420+
assert(VarDeclScopeMap.count(value) == 0 && "VarDecl appears twice");
421+
VarDeclScopeMap.insert({value, ASTScope});
422+
}
423+
return false;
424+
}
425+
bool lookInMembers(const DeclContext *) const override { return false; }
426+
#ifndef NDEBUG
427+
void startingNextLookupStep() override {}
428+
void finishingLookup(std::string) const override {}
429+
bool isTargetLookup() const override { return false; }
430+
#endif
431+
};
432+
Consumer consumer(ASTScope, VarDeclScopeMap);
433+
ASTScope->lookupLocalsOrMembers(consumer);
434+
393435
// Collapse BraceStmtScopes whose parent is a .*BodyScope.
394436
if (auto Parent = ASTScope->getParent().getPtrOrNull())
395437
if (Parent->getSourceRangeOfThisASTNode() ==
396438
ASTScope->getSourceRangeOfThisASTNode())
397-
return getOrCreateScope(Parent, FnScope, InlinedAt);
439+
return cache(getOrCreateScope(Parent, FnScope, InlinedAt));
398440

399441
// The calls to defer closures have cleanup source locations pointing to the
400442
// defer. Reparent them into the current debug scope.
401443
auto *AncestorScope = ASTScope->getParent().getPtrOrNull();
402444
while (AncestorScope && AncestorScope != FnASTScope &&
403445
!ScopeMap.count({AncestorScope, InlinedAt})) {
404446
if (auto *FD = dyn_cast_or_null<FuncDecl>(
405-
AncestorScope->getDeclIfAny().getPtrOrNull())) {
447+
AncestorScope->getDeclIfAny().getPtrOrNull())) {
406448
if (cast<DeclContext>(FD) != FunctionDC)
407-
return B.getCurrentDebugScope();
449+
return cache(B.getCurrentDebugScope());
408450

409451
// This is this function's own scope.
410452
// If this is the outermost BraceStmt scope, ignore it.
411453
if (AncestorScope == ASTScope->getParent().getPtrOrNull())
412-
return FnScope;
454+
return cache(FnScope);
413455
break;
414456
}
415457

416458
AncestorScope = AncestorScope->getParent().getPtrOrNull();
417459
};
418460

461+
// Create the scope and recursively its parents. getLookupParent implements a
462+
// special case for GuardBlockStmt, which is nested incorrectly.
463+
auto *ParentScope = ASTScope->getLookupParent().getPtrOrNull();
419464
const SILDebugScope *Parent =
420-
getOrCreateScope(ASTScope->getParent().getPtrOrNull(), FnScope, InlinedAt);
465+
getOrCreateScope(ParentScope, FnScope, InlinedAt);
421466
SourceLoc SLoc = ASTScope->getSourceRangeOfThisASTNode().Start;
422467
RegularLocation Loc(SLoc);
423-
SILScope = new (SGM.M)
468+
auto *SILScope = new (SGM.M)
424469
SILDebugScope(Loc, FnScope->getParentFunction(), Parent, InlinedAt);
425-
ScopeMap.insert({{ASTScope, InlinedAt}, SILScope});
426-
427-
assert(SILScope->getParentFunction() == &F &&
428-
"inlinedAt points to other function");
429-
430-
return SILScope;
470+
return cache(SILScope);
431471
}
432472

433473
void SILGenFunction::enterDebugScope(SILLocation Loc, bool isBindingScope) {

lib/SILGen/SILGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
366366
SourceLoc LastSourceLoc;
367367
using ASTScopeTy = ast_scope::ASTScopeImpl;
368368
const ASTScopeTy *FnASTScope = nullptr;
369+
using VarDeclScopeMapTy =
370+
llvm::SmallDenseMap<ValueDecl *, const ASTScopeTy *, 8>;
371+
/// The ASTScope each variable declaration belongs to.
372+
VarDeclScopeMapTy VarDeclScopeMap;
369373
/// Caches one SILDebugScope for each ASTScope.
370374
llvm::SmallDenseMap<std::pair<const ASTScopeTy *, const SILDebugScope *>,
371375
const SILDebugScope *, 16>

test/DebugInfo/for-scope.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ public func f(_ xs: [String?]) {
88
sink(x)
99
}
1010
}
11+
1112
// CHECK: sil_scope [[F:[0-9]+]] { loc "{{.*}}":5:13 parent @$s1a1fyySaySSSgGF
12-
// CHECK: sil_scope [[S0:[0-9]+]] { loc "{{.*}}":6:3 parent [[F]] }
13-
// CHECK: sil_scope [[S1:[0-9]+]] { loc "{{.*}}":6:15 parent [[S0]] }
14-
// CHECK: sil_scope [[S3:[0-9]+]] { loc "{{.*}}":7:9 parent [[S1]] }
15-
// CHECK: sil_scope [[S4:[0-9]+]] { loc "{{.*}}":7:13 parent [[S3]] }
13+
// CHECK: sil_scope [[S3:[0-9]+]] { loc "{{.*}}":6:3 parent [[F]] }
14+
// CHECK: sil_scope [[S4:[0-9]+]] { loc "{{.*}}":6:15 parent [[S3]] }
15+
// CHECK: sil_scope [[S5:[0-9]+]] { loc "{{.*}}":7:13 parent [[S4]] }
16+
// CHECK: sil_scope [[S6:[0-9]+]] { loc "{{.*}}":7:9 parent [[S4]] }
1617

17-
// CHECK: debug_value %[[X:.*]] : $Optional<String>, let, name "x", {{.*}}, scope [[S0]]
18-
// CHECK: retain_value %[[X]] : $Optional<String>, {{.*}}, scope [[S4]]
19-
// CHECK: debug_value %[[X1:[0-9]+]] : $String, let, name "x", {{.*}}, scope [[S3]]
20-
// CHECK: release_value %[[X1]] : $String, {{.*}}, scope [[S3]]
21-
// CHECK: release_value %[[X]] : $Optional<String>, {{.*}}, scope [[S3]]
18+
// CHECK: debug_value %[[X:.*]] : $Optional<String>, let, name "x", {{.*}}, scope [[S4]]
19+
// CHECK: retain_value %[[X]] : $Optional<String>, {{.*}}, scope [[S5]]
20+
// CHECK: debug_value %[[X1:[0-9]+]] : $String, let, name "x", {{.*}}, scope [[S6]]
21+
// CHECK: release_value %[[X1]] : $String, {{.*}}, scope [[S6]]
22+
// CHECK: release_value %[[X]] : $Optional<String>, {{.*}}, scope [[S6]]

test/DebugInfo/guard-let-scope.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ func f(c: AnyObject??) {
77
guard let x = x, let x = x else {
88
// CHECK: sil_scope [[S3:[0-9]+]] { {{.*}} parent @{{.*}}1f
99
// CHECK: sil_scope [[S4:[0-9]+]] { {{.*}} parent [[S3]] }
10-
// CHECK: sil_scope [[S5:[0-9]+]] { {{.*}} parent [[S4]] }
11-
// CHECK: sil_scope [[S6:[0-9]+]] { loc "{{.*}}":7:3 parent [[S4]] }
10+
// CHECK: sil_scope [[S5:[0-9]+]] { {{.*}} parent [[S3]] }
11+
// CHECK: sil_scope [[S6:[0-9]+]] { loc "{{.*}}":7:3 parent [[S5]] }
1212
// CHECK: sil_scope [[S7:[0-9]+]] { loc "{{.*}}":7:17 parent [[S6]] }
1313
// CHECK: sil_scope [[S8:[0-9]+]] { loc "{{.*}}":7:28 parent [[S7]] }
14-
// CHECK: debug_value %{{.*}} : $Optional<Optional<AnyObject>>, let, name "x"{{.*}} scope [[S4]]
15-
// CHECK: debug_value %{{.*}} : $Optional<AnyObject>, let, name "x", {{.*}} scope [[S6]]
16-
// CHECK: debug_value %{{.*}} : $AnyObject, let, name "x", {{.*}} scope [[S7]]
14+
// CHECK: debug_value %{{.*}} : $Optional<Optional<AnyObject>>, let, name "x"{{.*}} scope [[S5]]
15+
// CHECK: debug_value %{{.*}} : $Optional<AnyObject>, let, name "x", {{.*}} scope [[S7]]
16+
// CHECK: debug_value %{{.*}} : $AnyObject, let, name "x", {{.*}} scope [[S8]]
1717
fatalError()
1818
}
1919
// CHECK: function_ref {{.*3use.*}} scope [[S8]]

test/DebugInfo/guard-let-scope2.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public func f(x: String?) throws {
1818
}
1919
// CHECK: sil_scope [[S1:[0-9]+]] { {{.*}} parent @{{.*}}1f
2020
// CHECK: sil_scope [[S2:[0-9]+]] { {{.*}} parent [[S1]] }
21-
// CHECK: sil_scope [[S3:[0-9]+]] { {{.*}} parent [[S2]] }
21+
// CHECK: sil_scope [[S3:[0-9]+]] { {{.*}} parent [[S1]] }
2222
// CHECK: sil_scope [[S4:[0-9]+]] { {{.*}} parent [[S2]] }
2323
// CHECK: alloc_stack {{.*}} $SomeObject, let, name "s", {{.*}} scope [[S4]]
2424
guard let s = s else {

test/DebugInfo/guard-let-scope3.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ public class S {
77
private var c = [Int : C?]()
88
public func f(_ i: Int) throws -> C {
99
guard let x = c[i], let x else {
10-
// CHECK: sil_scope [[X1:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:5
11-
// CHECK: sil_scope [[X2:[0-9]+]] { loc "{{.*}}":[[@LINE-2]]:29
12-
// CHECK: debug_value {{.*}} : $Optional<C>, let, name "x", {{.*}}, scope [[X1]]
13-
// CHECK: debug_value %29 : $C, let, name "x", {{.*}}, scope [[X2]]
14-
// CHECK-NEXT: scope [[X2]]
10+
// CHECK: sil_scope [[P:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:5
11+
// CHECK: sil_scope [[X1:[0-9]+]] { loc "{{.*}}":[[@LINE-2]]:19 parent [[P]]
12+
// CHECK: sil_scope [[X2:[0-9]+]] { loc "{{.*}}":[[@LINE-3]]:29 parent [[X1]]
13+
// CHECK: sil_scope [[GUARD:[0-9]+]] { loc "{{.*}}":[[@LINE-4]]:36 parent [[P]]
14+
// CHECK: debug_value {{.*}} : $Optional<C>, let, name "x", {{.*}}, scope [[X1]]
15+
// CHECK: debug_value {{.*}} : $C, let, name "x", {{.*}}, scope [[X2]]
16+
// CHECK-NEXT: scope [[X2]]
1517
throw MyError()
18+
// CHECK: function_ref {{.*}}MyError{{.*}}:[[@LINE-1]]:13, scope [[GUARD]]
1619
}
1720
return x
1821
}

test/DebugInfo/if-let-scope.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %target-swift-frontend -g -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
2+
func use<T>(_ t: T) {}
3+
public func f(value: String?) {
4+
// CHECK: sil_scope [[S0:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:13
5+
if let value, let value = Int(value) {
6+
// CHECK: sil_scope [[S1:[0-9]+]] { loc "{{.*}}":[[@LINE-1]]:10
7+
// CHECK: sil_scope [[S2:[0-9]+]] { loc "{{.*}}":[[@LINE-2]]:29 parent [[S1]] }
8+
// CHECK: debug_value {{.*}} : $Optional<String>, let, name "value", {{.*}}, scope [[S0]]
9+
// CHECK: debug_value {{.*}} : $String, let, name "value", {{.*}}, scope [[S1]]
10+
// CHECK: debug_value {{.*}} : $Int, let, name "value", {{.*}}, scope [[S2]]
11+
use((value))
12+
}
13+
}

test/DebugInfo/inlinescopes.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ func inlined(_ x: Int64) -> Int64 {
2727
let result = transparent(x)
2828
// CHECK-DAG: ![[CALL]] = !DILocation(line: [[@LINE-1]], column: {{.*}}, scope: ![[INLINED1:.*]], inlinedAt: ![[INLINEDAT:.*]])
2929
// CHECK-DAG: ![[INLINEDAT]] = !DILocation({{.*}}scope: ![[INLINEDAT1:[0-9]+]]
30-
// CHECK-DAG: ![[INLINED1]] = distinct !DILexicalBlock(scope: ![[INLINED2:[0-9]+]]
31-
// CHECK-DAG: ![[INLINED2]] = distinct !DILexicalBlock(scope: ![[INLINED3:[0-9]+]]
30+
// CHECK-DAG: ![[INLINED1]] = distinct !DILexicalBlock(scope: ![[INLINED:[0-9]+]]
3231
// Check if the inlined and removed function still has the correct linkage name.
33-
// CHECK-DAG: ![[INLINED3]] = distinct !DISubprogram(name: "inlined", linkageName: "$s4main7inlinedys5Int64VADF"
32+
// CHECK-DAG: ![[INLINED]] = distinct !DISubprogram(name: "inlined", linkageName: "$s4main7inlinedys5Int64VADF"
3433
// TRANSPARENT-CHECK-NOT: !DISubprogram(name: "transparent"
3534
return result
3635
}

test/DebugInfo/let-scope.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -g -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
2+
func use<T>(_ t: T) {}
3+
public func f(value: (Int, Int)) {
4+
let (x, y) = value
5+
// CHECK: debug_value {{.*}}let, name "x", {{.*}}, scope [[LET:[0-9]+]]
6+
// CHECK: debug_value {{.*}}let, name "y", {{.*}}, scope [[LET]]
7+
use((x,y))
8+
}

test/DebugInfo/scopes.swift

Lines changed: 0 additions & 32 deletions
This file was deleted.

test/DebugInfo/shadowed-arg.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ public func f(i: Int) {
1717
// CHECK: ![[S3]] = distinct !DILexicalBlock(scope: ![[S1]],
1818
// SIL: sil_scope [[S1:[0-9]+]] { {{.*}} parent @$s4main1f1iySi_tF
1919
// SIL: sil_scope [[S2:[0-9]+]] { {{.*}} parent [[S1]] }
20+
// SIL: sil_scope [[S3:[0-9]+]] { {{.*}} parent [[S1]] }
2021
// SIL: debug_value %0 : $Int, let, name "i", argno 1,{{.*}}, scope [[S1]]
21-
// SIL: debug_value {{.*}} : $Array<Int>, let, name "i", {{.*}}, scope [[S2]]
22+
// SIL: debug_value {{.*}} : $Array<Int>, let, name "i", {{.*}}, scope [[S3]]

test/Macros/macro_expand_closure.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ func multiStatementInference() -> Int {
2020
// The closure intruduced by the macro expansion should not contain any inline
2121
// locations, but instead point directly into the macro buffer.
2222
// CHECK-SIL: sil_scope [[S0:[0-9]+]] { loc "@__swiftmacro_9MacroUser23multiStatementInferenceSiyF0cD0fMf_.swift":1:1 parent @$s9MacroUser23multiStatementInferenceSiyFSiyXEfU_
23-
// CHECK-SIL: sil_scope [[S1:[0-9]+]] { loc "@__swiftmacro_9MacroUser23multiStatementInferenceSiyF0cD0fMf_.swift":2:7 parent [[S0]] }
24-
// CHECK-SIL: sil_scope [[S2:[0-9]+]] { loc "@__swiftmacro_9MacroUser23multiStatementInferenceSiyF0cD0fMf_.swift":2:14 parent [[S1]] }
23+
// CHECK-SIL: sil_scope [[S2:[0-9]+]] { loc "@__swiftmacro_9MacroUser23multiStatementInferenceSiyF0cD0fMf_.swift":2:14 parent [[S0]] }
2524

2625
// CHECK-SIL: sil {{.*}} @$s9MacroUser23multiStatementInferenceSiyFSiyXEfU_
2726
// CHECK-SIL-NOT: return

test/SILOptimizer/capturepromotion-wrong-lexicalscope.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
// CHECK: destroy_value [[BOX_COPY]] : ${ var Int }, loc {{.*}}:33:11, scope 4
2020
// CHECK: [[CLOSURE:%[^,]+]] = partial_apply [callee_guaranteed] [[SPECIALIZED_F]]([[REGISTER_11]]) : $@convention(thin) (Int) -> Int, loc {{.*}}:33:11, scope 4
2121
// CHECK: [[BORROW:%.*]] = begin_borrow [lexical] [[CLOSURE]]
22-
// CHECK: debug_value [[BORROW]] : $@callee_guaranteed () -> Int, let, name "f", loc {{.*}}:33:7, scope 5
23-
// CHECK: [[CLOSURE_COPY:%[^,]+]] = copy_value [[BORROW]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:10, scope 5
22+
// CHECK: debug_value [[BORROW]] : $@callee_guaranteed () -> Int, let, name "f", loc {{.*}}:33:7, scope 6
23+
// CHECK: [[CLOSURE_COPY:%[^,]+]] = copy_value [[BORROW]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:10, scope 6
2424
// There used to be an end_borrow here. We leave an emptyline here to preserve line numbers.
25-
// CHECK: destroy_value [[CLOSURE]] : $@callee_guaranteed () -> Int, loc {{.*}}:35:1, scope 5
26-
// CHECK: destroy_value [[BOX]] : ${ var Int }, loc {{.*}}:35:1, scope 5
27-
// CHECK: return [[CLOSURE_COPY]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:3, scope 5
25+
// CHECK: destroy_value [[CLOSURE]] : $@callee_guaranteed () -> Int, loc {{.*}}:35:1, scope 6
26+
// CHECK: destroy_value [[BOX]] : ${ var Int }, loc {{.*}}:35:1, scope 6
27+
// CHECK: return [[CLOSURE_COPY]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:3, scope 6
2828
// CHECK: }
2929

3030

0 commit comments

Comments
 (0)