Skip to content

Commit fc43e46

Browse files
committed
Sema: Track multiple pending decl body TRCs in TypeRefinementContextBuilder.
NFC. Lays the groundwork to use `DeclBodyContextStack` to build type refinement context trees for declarations that have multiple bodies. For example pattern binding declarations may introduce multiple bindings, each with their own init expression. Each init may need a distinct body TRC.
1 parent 9ea3146 commit fc43e46

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
388388
/// contexts. TRCs in this stack should be pushed onto \p ContextStack when
389389
/// \p BodyStmt is encountered.
390390
struct DeclBodyContextInfo {
391-
TypeRefinementContext *TRC;
392391
Decl *Decl;
393-
Stmt *BodyStmt;
392+
llvm::DenseMap<ASTNode, TypeRefinementContext *> BodyTRCs;
394393
};
395394
std::vector<DeclBodyContextInfo> DeclBodyContextStack;
396395

@@ -419,11 +418,10 @@ class TypeRefinementContextBuilder : private ASTWalker {
419418
ContextStack.push_back(Info);
420419
}
421420

422-
void pushDeclBodyContext(TypeRefinementContext *TRC, Decl *D, Stmt *S) {
421+
void pushDeclBodyContext(TypeRefinementContext *TRC, Decl *D, ASTNode Body) {
423422
DeclBodyContextInfo Info;
424-
Info.TRC = TRC;
425423
Info.Decl = D;
426-
Info.BodyStmt = S;
424+
Info.BodyTRCs.insert({Body, TRC});
427425

428426
DeclBodyContextStack.push_back(Info);
429427
}
@@ -491,6 +489,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
491489

492490
while (!DeclBodyContextStack.empty() &&
493491
DeclBodyContextStack.back().Decl == D) {
492+
// All pending body TRCs should have been consumed.
493+
assert(DeclBodyContextStack.back().BodyTRCs.empty());
494494
DeclBodyContextStack.pop_back();
495495
}
496496

@@ -771,19 +771,20 @@ class TypeRefinementContextBuilder : private ASTWalker {
771771
return Action::Continue(S);
772772
}
773773

774-
/// Consumes the top TRC from \p DeclBodyContextStack and pushes it onto the
775-
/// \p Context stack if the given \p Stmt is the matching body statement.
776-
/// Returns \p true if a context was pushed.
777-
bool consumeDeclBodyContextIfNecessary(Stmt *S) {
774+
/// Attempts to consume a TRC from the `BodyTRCs` of the top of
775+
/// `DeclBodyContextStack`. Returns \p true if a context was pushed.
776+
template <typename T>
777+
bool consumeDeclBodyContextIfNecessary(T Body) {
778778
if (DeclBodyContextStack.empty())
779779
return false;
780780

781-
auto Info = DeclBodyContextStack.back();
782-
if (S != Info.BodyStmt)
781+
auto &Info = DeclBodyContextStack.back();
782+
auto Iter = Info.BodyTRCs.find(Body);
783+
if (Iter == Info.BodyTRCs.end())
783784
return false;
784785

785-
pushContext(Info.TRC, Info.BodyStmt);
786-
DeclBodyContextStack.pop_back();
786+
pushContext(Iter->getSecond(), Body);
787+
Info.BodyTRCs.erase(Iter);
787788
return true;
788789
}
789790

0 commit comments

Comments
 (0)