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.
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.
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().