[cfe-dev] Rewriting modified named declarations

Jon Reeves via cfe-dev cfe-dev at lists.llvm.org
Mon Jun 15 18:57:34 PDT 2020

Just to follow up on this for posterity, I realized some time later that
this can easily be done using the QualType "print" method (as opposed to
the usual getAsString). This method has an argument called "PlaceHolder"
which can be used to serialize a concrete type declaration with an
identifier instead of just getting the usual abstract declaration. I wasn't
able to find any documentation on this, but it's relatively clear from
reading the code in TypePrinter.

So I guess I still have a lingering question about whether this is the
"best" way to do this, but it's extremely simple and would probably be
pretty hard to improve upon. If anyone has further input on this of course
it's more than appreciated, but I would otherwise consider it cased closed.

Thanks again!

On Fri, Jun 12, 2020 at 11:09 AM Jon Reeves <jon.r.reeves at gmail.com> wrote:

> Hi cfe-dev!
> I'm definitely a noob to clang development but I'm enjoying getting to
> know the various APIs and trying to transition from playing around to doing
> some useful work.
> I'm doing my best to self-serve wherever possible, but there are a couple
> of things I've run into where I could really use some guidance from people
> who are more experienced here. The first of these is in the broad category
> of "re-serializing" (possibly modified) code from AST nodes without
> strictly relying on the original source code text (as in the case of the
> rewriter classes as I understand them).
> As a concrete but probably contrived example, let's say you've used your
> favorite AST visitor class to visit a named declaration that is a two
> dimensional array of function pointers. In code it looks something like
> this:
> void (*twoDimCallbacks[3][3])(void);
> The AST node you'll get from this is a NamedDecl type, where you can ask
> for its string name (which will yield "twoDimCallbacks" as a string), and
> its original qualified type, on which you can then call
> getAsString(), which will give you "void (*[3][3])(void)".
> Now let's say you want to modify and rewrite this declaration into some
> totally unrelated stream. Maybe you're trying to create some support
> functions that aren't strict re-writes of the original code. Essentially
> what you want is a function in your tool that looks like this:
> void serializeNewNamedDecl(std::ostream &stream, std::string &name,
> QualType declType);
> If you didn't have to support arrays or function pointers, implementing
> this function would actually be somewhat trivial, since all of the type
> specifiers would just be on the left side. You could do something like:
> stream << declType.getAsString() << " " << name;
> To do this with arrays and function pointers though, you have to write
> code with some semantic understanding of the type declaration and figure
> out exactly where the name should go. It seems to me like this must already
> exist somewhere in the various clang libraries.
> And so after much typing, I arrive at my question: what is the "clangiest"
> way to do this? Is the answer really just to write a custom serializer? Is
> it to do a search and replace on the original source code line where the
> original NamedDecl was found? What if we want to actually modify the type
> in some way? The common search and replace technique breaks down here.
> Is there a class that can generate a new NamedDecl and pretty print it?
> Apologies if this has already been covered somewhere in the history of
> this forum. Appreciate whatever response anyone is willing to formulate.
> Thanks in advance!
> -Jon Reeves
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200615/4d3a4fdf/attachment.html>

More information about the cfe-dev mailing list