@@ -1583,6 +1583,12 @@ void StmtChecker::typeCheckASTNode(ASTNode &node) {
1583
1583
return ;
1584
1584
}
1585
1585
1586
+ if (auto *Cond = node.dyn_cast <StmtConditionElement *>()) {
1587
+ bool IsFalsable; // ignored
1588
+ TypeChecker::typeCheckStmtConditionElement (*Cond, IsFalsable, DC);
1589
+ return ;
1590
+ }
1591
+
1586
1592
llvm_unreachable (" Type checking null ASTNode" );
1587
1593
}
1588
1594
@@ -1910,6 +1916,19 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
1910
1916
class ASTNodeFinder : public ASTWalker {
1911
1917
SourceManager &SM;
1912
1918
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;
1913
1932
ASTNode *FoundNode = nullptr ;
1914
1933
1915
1934
// / The innermost DeclContext that contains \c FoundNode.
@@ -1977,6 +1996,20 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
1977
1996
}
1978
1997
// Already walked into.
1979
1998
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
+ }
1980
2013
}
1981
2014
1982
2015
return Action::Continue (S);
@@ -2017,7 +2050,8 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2017
2050
SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, D->getEndLoc ());
2018
2051
if (!(SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc)) {
2019
2052
if (!isa<TopLevelCodeDecl>(D)) {
2020
- FoundNode = new ASTNode (D);
2053
+ FoundNodeStorage = ASTNode (D);
2054
+ FoundNode = &FoundNodeStorage;
2021
2055
}
2022
2056
}
2023
2057
}
0 commit comments