@@ -1583,6 +1583,12 @@ void StmtChecker::typeCheckASTNode(ASTNode &node) {
15831583 return ;
15841584 }
15851585
1586+ if (auto *Cond = node.dyn_cast <StmtConditionElement *>()) {
1587+ bool IsFalsable; // ignored
1588+ TypeChecker::typeCheckStmtConditionElement (*Cond, IsFalsable, DC);
1589+ return ;
1590+ }
1591+
15861592 llvm_unreachable (" Type checking null ASTNode" );
15871593}
15881594
@@ -1910,6 +1916,19 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
19101916 class ASTNodeFinder : public ASTWalker {
19111917 SourceManager &SM;
19121918 SourceLoc Loc;
1919+
1920+ // / When the \c ASTNode that we want to check was found inside a brace
1921+ // / statement, we need to store a *reference* to the element in the
1922+ // / \c BraceStmt. When the brace statement gets type checked for result
1923+ // / builders its elements will be updated in-place, which makes
1924+ // / \c FoundNodeRef now point to the type-checked replacement node. We need
1925+ // / this behavior.
1926+ // /
1927+ // / But for all other cases, we just want to store a plain \c ASTNode. To
1928+ // / make sure we free the \c ASTNode again, we store it in
1929+ // / \c FoundNodeStorage and set \c FoundNodeRef to point to
1930+ // / \c FoundNodeStorage.
1931+ ASTNode FoundNodeStorage;
19131932 ASTNode *FoundNode = nullptr ;
19141933
19151934 // / The innermost DeclContext that contains \c FoundNode.
@@ -1977,6 +1996,20 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
19771996 }
19781997 // Already walked into.
19791998 return Action::Stop ();
1999+ } else if (auto Conditional = dyn_cast<LabeledConditionalStmt>(S)) {
2000+ for (StmtConditionElement &Cond : Conditional->getCond ()) {
2001+ if (SM.isBeforeInBuffer (Loc, Cond.getStartLoc ())) {
2002+ break ;
2003+ }
2004+ SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, Cond.getEndLoc ());
2005+ if (SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc) {
2006+ continue ;
2007+ }
2008+
2009+ FoundNodeStorage = ASTNode (&Cond);
2010+ FoundNode = &FoundNodeStorage;
2011+ return Action::Stop ();
2012+ }
19802013 }
19812014
19822015 return Action::Continue (S);
@@ -2017,7 +2050,8 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
20172050 SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, D->getEndLoc ());
20182051 if (!(SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc)) {
20192052 if (!isa<TopLevelCodeDecl>(D)) {
2020- FoundNode = new ASTNode (D);
2053+ FoundNodeStorage = ASTNode (D);
2054+ FoundNode = &FoundNodeStorage;
20212055 }
20222056 }
20232057 }
0 commit comments