@@ -529,7 +529,7 @@ class ASTScopeImpl {
529529 // A local binding is a basically a local variable defined in that very scope
530530 // It is not an instance variable or inherited type.
531531
532- static bool lookupLocalBindingsInPattern (Pattern *p,
532+ static bool lookupLocalBindingsInPattern (const Pattern *p,
533533 DeclVisibilityKind vis,
534534 DeclConsumer consumer);
535535
@@ -1933,6 +1933,42 @@ class ForEachPatternScope final : public ASTScopeImpl {
19331933 bool isLabeledStmtLookupTerminator () const override ;
19341934};
19351935
1936+ // / The parent scope for a 'case' statement, consisting of zero or more
1937+ // / CaseLabelItemScopes, followed by a CaseStmtBodyScope.
1938+ // /
1939+ // / +------------------------------------------------------------------
1940+ // / | CaseStmtScope
1941+ // / +------------------------------------------------------------------
1942+ // / | +--------------------------+
1943+ // / | | CaseLabelItemScope: |
1944+ // / | +--------------------------+
1945+ // / | case .foo(let x, let y) where | condition(x, y), |
1946+ // / | ^------^--------------------^--^ |
1947+ // / | this guard expression sees first 'x'/'y' |
1948+ // / | +--------------------------+
1949+ // / |
1950+ // / | +--------------------------+
1951+ // / | | CaseLabelItemScope: |
1952+ // / | +--------------------------+
1953+ // / | .foo(let x, let y) where | condition(x, y), |
1954+ // / | ^------^--------------------^--^ |
1955+ // / | this guard expression sees second 'x'/'y' |
1956+ // / | +--------------------------+
1957+ // / |
1958+ // / | .bar(let x, let y)
1959+ // / | this case label item doesn't have a guard, so no
1960+ // / | scope is created.
1961+ // / |
1962+ // / | +----------------------------------------------------------------
1963+ // / | | CaseStmtBodyScope:
1964+ // / | +----------------------------------------------------------------
1965+ // / | | {
1966+ // / | | ... x, y <-- body sees "joined" 'x'/'y' created by parser
1967+ // / | | }
1968+ // / | +----------------------------------------------------------------
1969+ // / |
1970+ // / +------------------------------------------------------------------
1971+
19361972class CaseStmtScope final : public AbstractStmtScope {
19371973public:
19381974 CaseStmt *const stmt;
@@ -1945,17 +1981,66 @@ class CaseStmtScope final : public AbstractStmtScope {
19451981private:
19461982 void expandAScopeThatDoesNotCreateANewInsertionPoint (ScopeCreator &);
19471983
1984+ public:
1985+ std::string getClassName () const override ;
1986+ Stmt *getStmt () const override { return stmt; }
1987+ };
1988+
1989+ // / The scope used for the guard expression in a case statement. Any
1990+ // / variables bound by the case label item's pattern are visible in
1991+ // / this scope.
1992+ class CaseLabelItemScope final : public ASTScopeImpl {
1993+ public:
1994+ CaseLabelItem item;
1995+ CaseLabelItemScope (const CaseLabelItem &item) : item(item) {}
1996+ virtual ~CaseLabelItemScope () {}
1997+
1998+ protected:
1999+ ASTScopeImpl *expandSpecifically (ScopeCreator &scopeCreator) override ;
2000+
2001+ private:
2002+ void expandAScopeThatDoesNotCreateANewInsertionPoint (ScopeCreator &);
2003+
19482004public:
19492005 std::string getClassName () const override ;
19502006 SourceRange
19512007 getSourceRangeOfThisASTNode (bool omitAssertions = false ) const override ;
1952- Stmt *getStmt () const override { return stmt; }
19532008
19542009protected:
19552010 bool lookupLocalsOrMembers (ArrayRef<const ASTScopeImpl *>,
19562011 ASTScopeImpl::DeclConsumer) const override ;
19572012};
19582013
2014+ // / The scope used for the body of a 'case' statement.
2015+ // /
2016+ // / If the 'case' statement has multiple case label items, each label
2017+ // / item's pattern must bind the same variables; the parser creates
2018+ // / "fake" variables to represent the join of the variables bound by
2019+ // / each pattern.
2020+ // /
2021+ // / These "fake" variables are visible in the 'case' statement body.
2022+ class CaseStmtBodyScope final : public ASTScopeImpl {
2023+ public:
2024+ CaseStmt *const stmt;
2025+ CaseStmtBodyScope (CaseStmt *e) : stmt(e) {}
2026+ virtual ~CaseStmtBodyScope () {}
2027+
2028+ protected:
2029+ ASTScopeImpl *expandSpecifically (ScopeCreator &scopeCreator) override ;
2030+
2031+ private:
2032+ void expandAScopeThatDoesNotCreateANewInsertionPoint (ScopeCreator &);
2033+
2034+ public:
2035+ std::string getClassName () const override ;
2036+ SourceRange
2037+ getSourceRangeOfThisASTNode (bool omitAssertions = false ) const override ;
2038+ protected:
2039+ bool lookupLocalsOrMembers (ArrayRef<const ASTScopeImpl *>,
2040+ ASTScopeImpl::DeclConsumer) const override ;
2041+ bool isLabeledStmtLookupTerminator () const override ;
2042+ };
2043+
19592044class BraceStmtScope final : public AbstractStmtScope {
19602045
19612046public:
0 commit comments