@@ -773,33 +773,63 @@ CaseStmt::CaseStmt(CaseParentKind parentKind, SourceLoc itemIntroducerLoc,
773773 MutableArrayRef<CaseLabelItem> items{getTrailingObjects<CaseLabelItem>(),
774774 static_cast <size_t >(Bits.CaseStmt .NumPatterns )};
775775
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.
779776 for (unsigned i : range (Bits.CaseStmt .NumPatterns )) {
780777 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+ });
785784 }
786785}
787786
788787namespace {
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);
803833}
804834
805835struct FallthroughFinder : ASTWalker {
0 commit comments