@@ -5487,18 +5487,20 @@ class ReferenceCollector : private SourceEntityWalker {
5487
5487
};
5488
5488
5489
5489
// / Similar to the \c ReferenceCollector but collects references in all scopes
5490
- // / without any starting point in each scope.
5490
+ // / without any starting point in each scope. In addition, it tracks the number
5491
+ // / of references to a decl in a given scope.
5491
5492
class ScopedDeclCollector : private SourceEntityWalker {
5492
5493
public:
5493
5494
using DeclsTy = llvm::DenseSet<const Decl *>;
5495
+ using RefDeclsTy = llvm::DenseMap<const Decl *, /* numRefs*/ unsigned >;
5494
5496
5495
5497
private:
5496
- using ScopedDeclsTy = llvm::DenseMap<const Stmt *, DeclsTy >;
5498
+ using ScopedDeclsTy = llvm::DenseMap<const Stmt *, RefDeclsTy >;
5497
5499
5498
5500
struct Scope {
5499
5501
DeclsTy DeclaredDecls;
5500
- DeclsTy *ReferencedDecls;
5501
- Scope (DeclsTy *ReferencedDecls) : DeclaredDecls(),
5502
+ RefDeclsTy *ReferencedDecls;
5503
+ Scope (RefDeclsTy *ReferencedDecls) : DeclaredDecls(),
5502
5504
ReferencedDecls (ReferencedDecls) {}
5503
5505
};
5504
5506
@@ -5514,7 +5516,7 @@ class ScopedDeclCollector : private SourceEntityWalker {
5514
5516
walk (Node);
5515
5517
}
5516
5518
5517
- DeclsTy *getReferencedDecls (Stmt *Scope) {
5519
+ const RefDeclsTy *getReferencedDecls (Stmt *Scope) const {
5518
5520
auto Res = ReferencedDecls.find (Scope);
5519
5521
if (Res == ReferencedDecls.end ())
5520
5522
return nullptr ;
@@ -5528,7 +5530,7 @@ class ScopedDeclCollector : private SourceEntityWalker {
5528
5530
5529
5531
ScopeStack.back ().DeclaredDecls .insert (D);
5530
5532
if (isa<DeclContext>(D))
5531
- ScopeStack.back ().ReferencedDecls -> insert (D) ;
5533
+ (* ScopeStack.back ().ReferencedDecls )[D] += 1 ;
5532
5534
return true ;
5533
5535
}
5534
5536
@@ -5539,8 +5541,10 @@ class ScopedDeclCollector : private SourceEntityWalker {
5539
5541
if (!E->isImplicit ()) {
5540
5542
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
5541
5543
if (auto *D = DRE->getDecl ()) {
5544
+ // If we have a reference that isn't declared in the same scope,
5545
+ // increment the number of references to that decl.
5542
5546
if (!D->isImplicit () && !ScopeStack.back ().DeclaredDecls .count (D))
5543
- ScopeStack.back ().ReferencedDecls -> insert (D) ;
5547
+ (* ScopeStack.back ().ReferencedDecls )[D] += 1 ;
5544
5548
}
5545
5549
}
5546
5550
}
@@ -5563,9 +5567,10 @@ class ScopedDeclCollector : private SourceEntityWalker {
5563
5567
// Add any referenced decls to the parent scope that weren't declared
5564
5568
// there.
5565
5569
auto &ParentStack = ScopeStack[NumScopes - 2 ];
5566
- for (auto *D : *ScopeStack.back ().ReferencedDecls ) {
5570
+ for (auto DeclAndNumRefs : *ScopeStack.back ().ReferencedDecls ) {
5571
+ auto *D = DeclAndNumRefs.first ;
5567
5572
if (!ParentStack.DeclaredDecls .count (D))
5568
- ParentStack.ReferencedDecls -> insert (D) ;
5573
+ (* ParentStack.ReferencedDecls )[D] += DeclAndNumRefs. second ;
5569
5574
}
5570
5575
}
5571
5576
ScopeStack.pop_back ();
@@ -6119,7 +6124,10 @@ class AsyncConverter : private SourceEntityWalker {
6119
6124
// The body of those statements will include the decls if they've been
6120
6125
// referenced, so shadowing is still avoided there.
6121
6126
if (auto *ReferencedDecls = ScopedDecls.getReferencedDecls (S)) {
6122
- addNewScope (*ReferencedDecls);
6127
+ llvm::DenseSet<const Decl *> Decls;
6128
+ for (auto DeclAndNumRefs : *ReferencedDecls)
6129
+ Decls.insert (DeclAndNumRefs.first );
6130
+ addNewScope (Decls);
6123
6131
} else {
6124
6132
addNewScope ({});
6125
6133
}
@@ -6740,8 +6748,8 @@ class AsyncConverter : private SourceEntityWalker {
6740
6748
6741
6749
void addNewScope (const llvm::DenseSet<const Decl *> &Decls) {
6742
6750
ScopedNames.push_back ({});
6743
- for (auto *D : Decls) {
6744
- auto Name = getDeclName (D );
6751
+ for (auto DeclAndNumRefs : Decls) {
6752
+ auto Name = getDeclName (DeclAndNumRefs );
6745
6753
if (!Name.empty ())
6746
6754
ScopedNames.back ().insert (Name);
6747
6755
}
0 commit comments