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
207218const 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
433473void SILGenFunction::enterDebugScope (SILLocation Loc, bool isBindingScope) {
0 commit comments