<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 17, 2020 at 6:11 AM John McCall via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>




<div>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">Furthermore, I think expressions are important to consider,<br></p></div><div style="white-space:normal"><p dir="auto">
because the practical limitations on finding the semicolon after<br>
an expression are exactly the same as finding it after <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px 0.4em" bgcolor="#F7F7F7">break</code>.<br></p></div></div></div></blockquote><div>To spell this out a little more: formally in `foo();` there's an expression-statement which consists of a the call expression and the semicolon. But clang just uses the CallExpr node to represent both, and CallExpr obviously(?) shouldn't include the semicolon in its source range.</div><div><br></div><div>Alex: I think the Syntax library might be more suitable for tasks that need this precise info such as refactoring (and it doesn't suffer in the same way from the multiple masters problem). Unfortunately it's not complete.</div><div><br></div><div>The clang::syntax::TokenBuffer class allows you to capture the expanded token stream (bounds and kind of every token) as the parse runs (using TokenCollector). Effectively this lets you opt into making clang record more token-level info at the cost of memory. You then have to poke at this token stream yourself to find the semicolons you're after.</div><div><br></div><div>The rest of the Syntax library ("syntax trees") uses a clang AST to build up a true syntactic (grammar-based) tree out of these tokens. "TEST_F(SyntaxTreeTest, While)" in TreeTest.cpp shows how this includes the semicolons of the (grammatical) BreakStatement.</div><div>The plan is/was to make it easy to then map between semantic and syntactic nodes, e.g. AST BreakStmt to the corresponding syntax BreakStatement. This hasn't been implemented yet I think.</div></div></div>