Keep in mind that the body of a for statement can be not only a CompoundStmt ending in tok::r_brace, but any statement, including another “for” statement, which in turn could end in either a semicolon or brace. As I recall, getLocEnd in any of these cases will point to the token before either the “;” or the “}”, but you might want to check that. And you can probably check the result of loc = Lexer::findLocationAfterToken(…) for loc.isValid() to see if the token was indeed found there.

It seems like some generic Stmt call such as getLocForEndOfStmt() would really be useful.


Thank you for your remark.

As a matter of fact, I take into account the two following situations:

- if the body of the for is a compound statement, I expect it to be delimited by braces. Therefore, I call getLocEnd() and expect it to point just before the ending brace, then getLocForEndOfToken() to get the end.

- otherwise, I expect it to be a statement that ends with a semicolom. In this case I call findLocationAfterToken() as kindly suggested by other people in this thread

I tried with a large benchmark (SPEC2006) and it seems that it works.

And I agree with your last statement :stuck_out_tongue:

- Antoine

That’s interesting, as I’m doing code instrumentation and was doing something similar. But there are exceptions, such as:

for (…)
for (…)
{ … }

in which case the body is not a compound statement, and the getLocEnd() call points to just before the ending brace. Likewise an if, while, switch or similar statement immediately after the for. What I ended up doing (not pretty) is getting the character at the getLocEnd() position and seeing if it is a ‘}’. If so, I use getLocWithOffset(1) to point past, else use findLocationAfterToken(). You can look at the data with a call to SourceManager’s getCharacterData().

Dammit, you're right ! I now use your approach.
Thank you !

- Antoine