As I said before, I might not understand what you're trying
> to do. That said, I think that changing the code is a
> superset of changing the AST, so I don't understand why it's
> harder to do certain things that way. It of course requires
> a very precise mapping of AST nodes to source code, which
> clang luckily enough has. It also requires that you still
> want to do C++ (if you don't, that would be a case where
> what I say clarly does not apply).
My argumentation is that if the Clang front-end is used more and more as
a generic source-to-source translator, at some point we will need some
features helping the programmers to do so.
For example, just think to generating code for some kind of
heterogeneous accelerators, for example GPU. You need to outline some
pieces of code to new functions and it is quite complicated to do it in
the general case at the source level. Even at the AST level with more
suitable abstractions it is already difficult, as we can see in other
source-to-source compilers (as with ROSE Compiler & PIPS I know)
> As for changes of internal representation getting in your
> way - how's that better when you directly work on the AST -
> on the contrary, I expect subtle changes to the invariants
> of the AST to make it much harder to still produce correct
> ASTs by shoving around AST nodes, instead of making textual
> changes.
That is true. But for quite complex transformation work, I'm not sure
there is another way...
> And third, if you ever want the changes to go back to the
> programmer in code form, you suddenly need to care about
> formatting etc, and minimally disruptive changes to the
> text.
Of course, I assume in the "higher level" support that we need, we keep
information on all the formatting stuff. 
But anyway, it is an intractable issue per se (transformation on code
with a macro expansion, what is the very semantics of a comment
envisioned by the programmer at some position in the code...), but we can
provide some support for simple cases.
> I don't understand yet why you think the direct tree
> transformation is per se cleaner.
Because at some point of transformation complexity, it is cleaner to
invest in some common high-end source-to-source transformation support
and rely on it to develop all the complex tools, rather than trying to
do too complex stuff with string transformations.
But it is related to what we expect to do with the tool and it may not
apply to you. I understand it may not be the mainstream use for
Clang.
For some of our use cases (not using Clang), have a look to
par4all.org for example.