@@ -773,33 +773,63 @@ CaseStmt::CaseStmt(CaseParentKind parentKind, SourceLoc itemIntroducerLoc,
773
773
MutableArrayRef<CaseLabelItem> items{getTrailingObjects<CaseLabelItem>(),
774
774
static_cast <size_t >(Bits.CaseStmt .NumPatterns )};
775
775
776
- // At the beginning mark all of our var decls as being owned by this
777
- // statement. In the typechecker we wireup the case stmt var decl list since
778
- // we know everything is lined up/typechecked then.
779
776
for (unsigned i : range (Bits.CaseStmt .NumPatterns )) {
780
777
new (&items[i]) CaseLabelItem (caseLabelItems[i]);
781
- items[i].getPattern ()->markOwnedByStatement (this );
782
- }
783
- for (auto *vd : getCaseBodyVariables ()) {
784
- vd->setParentPatternStmt (this );
778
+ // Mark the CaseStmt as the parent for any canonical VarDecls in the
779
+ // pattern.
780
+ items[i].getPattern ()->forEachVariable ([&](VarDecl *VD) {
781
+ if (!VD->getParentVarDecl ())
782
+ VD->setParentPatternStmt (this );
783
+ });
785
784
}
786
785
}
787
786
788
787
namespace {
789
- static ArrayRef<VarDecl *>
790
- getCaseVarDecls (ASTContext &ctx, ArrayRef<CaseLabelItem> labelItems) {
791
- // Grab the first case label item pattern and use it to initialize the case
792
- // body var decls.
793
- SmallVector<VarDecl *, 4 > tmp;
794
- labelItems.front ().getPattern ()->collectVariables (tmp);
795
- return ctx.AllocateTransform <VarDecl *>(
796
- llvm::ArrayRef (tmp), [&](VarDecl *vOld) -> VarDecl * {
797
- auto *vNew = new (ctx) VarDecl (
798
- /* IsStatic*/ false , vOld->getIntroducer (), vOld->getNameLoc (),
799
- vOld->getName (), vOld->getDeclContext ());
800
- vNew->setImplicit ();
801
- return vNew;
802
- });
788
+ // / Produces an array of internal case body variables, and binds all of the
789
+ // / pattern variables that occur within the case to their "parent" pattern
790
+ // / variables, forming chains of variables with the same name.
791
+ // /
792
+ // / Given a case such as:
793
+ // / \code
794
+ // / case .a(let x), .b(let x), .c(let x):
795
+ // / \endcode
796
+ // /
797
+ // / Each case item contains a (different) pattern variable named `x`. This
798
+ // / function will set the "parent" variable of the second and third `x`
799
+ // / variables to the `x` variable immediately to its left. A fourth `x` will be
800
+ // / the body case variable, whose parent will be set to the `x` within the final
801
+ // / case item.
802
+ static ArrayRef<VarDecl *> getCaseVarDecls (ASTContext &ctx,
803
+ ArrayRef<CaseLabelItem> labelItems) {
804
+ SmallVector<VarDecl *, 4 > caseVars;
805
+ llvm::SmallDenseMap<Identifier, VarDecl *, 4 > allVars;
806
+
807
+ auto foundVar = [&](VarDecl *VD) {
808
+ if (!VD->hasName ())
809
+ return ;
810
+
811
+ auto &entry = allVars[VD->getName ()];
812
+ if (entry) {
813
+ VD->setParentVarDecl (entry);
814
+ } else {
815
+ auto *caseVar = new (ctx) VarDecl (
816
+ /* IsStatic*/ false , VD->getIntroducer (), VD->getNameLoc (),
817
+ VD->getName (), VD->getDeclContext ());
818
+ caseVar->setImplicit ();
819
+ caseVars.push_back (caseVar);
820
+ }
821
+ entry = VD;
822
+ };
823
+
824
+ for (auto &caseItem : labelItems)
825
+ caseItem.getPattern ()->forEachVariable (foundVar);
826
+
827
+ // Now that we've collected the case variables, ensure they're parented to
828
+ // the last pattern variables we saw.
829
+ for (auto caseVar : caseVars)
830
+ foundVar (caseVar);
831
+
832
+ return ctx.AllocateCopy (caseVars);
803
833
}
804
834
805
835
struct FallthroughFinder : ASTWalker {
0 commit comments