We already have children() but not children() const, which is causing some problems for me on an out of tree project. Most of the changes here are mechanical, except for the work done to ConstStmtIterator, which cheats and uses a const_cast. Since none of these are *actually* const, this should not trigger UB.
As I mentioned to Craig Topper recently on another review, generally when implementing const and non-const overloads the non-const is implemented in terms of the const overload (& const_casts away const on the result). This ensures no UB if the const overload is called on a truly const object. Even if there aren't any truly const Stmts today, I'd still prefer the code be written so as not to assume they couldn't exist.
In practice, this is really hard to do because there's no such thing as a const_iterator_cast operation to convert a const_iterator into an iterator, unless you have the underlying container handy. Since many of these uses do not have an underlying container (they're often trailing objects), I'm not certain this is practical (though I agree with the reasoning). Suggestions welcome, however.
If this is adding const, can you use a weaker cast? (I guess what would be ideal here would be implicit_cast - if you're interested you could add that - otherwise... yeah, I guess static_cast could do other nasty things, etc, so there's nothing good)
Maybe I'm missing something - what stops code from doing this conversion implicitly/accidentally all over the place? (I would've expecetd cast_away_const to be a friend or something, to only allow the conversion through this explicit call/operation)
The forward reference is needed because ConstStmtIterator is defined below StmtIterator. If I use class rather than struct, then MSVC diagnoses because of the mismatched class-key (which is a pretty low-value diagnostic, but I see no reason to disable it either).