[cfe-dev] Is ASTPrinter supposed to emit valid C++ code?

Roman Popov via cfe-dev cfe-dev at lists.llvm.org
Wed Oct 4 11:29:21 PDT 2017

So here is a reproducer for original email letter:

 template <typename Type1, typename Type2>
 struct test {
     typedef test this_t;  // ASTPrint output : typedef test<Type1, Type2>

 template <typename TT>
 struct  test<TT, int>  {
      typedef test this_t;  // ASTPrint output : typedef
test<type-parameter-0-0, int> this_t;

And here is AST Dump:

|-ClassTemplateDecl 0x4f6ad80 <simple.cpp:1:2, line:4:2> line:2:9 test
| |-TemplateTypeParmDecl 0x4f6ab88 <line:1:12, col:21> col:21 typename
depth 0 index 0 Type1
| |-TemplateTypeParmDecl 0x4f6ac28 <col:28, col:37> col:37 typename depth 0
index 1 Type2
| `-CXXRecordDecl 0x4f6ace8 <line:2:2, line:4:2> line:2:9 struct test
|   |-CXXRecordDecl 0x4f6b020 <col:2, col:9> col:9 implicit referenced
struct test
|   `-TypedefDecl 0x4f6b0c8 <line:3:6, col:19> col:19 this_t 'test<Type1,
|     `-InjectedClassNameType 0x4f6af90 'test<Type1, Type2>' dependent
|       `-CXXRecord 0x4f6ace8 'test'
`-ClassTemplatePartialSpecializationDecl 0x4f6b320 <line:6:2, line:9:2>
line:7:10 struct test definition
  |-TemplateArgument type 'type-parameter-0-0'
  |-TemplateArgument type 'int'
  |-*TemplateTypeParmDecl 0x4f6b140 <line:6:12, col:21> col:21 referenced
typename depth 0 index 0 TT*
  |-CXXRecordDecl 0x4f6b5b0 <line:7:2, col:10> col:10 implicit referenced
struct test
  `-TypedefDecl 0x4f6b658 <line:8:7, col:20> col:20 this_t
'test<type-parameter-0-0, int>'
    `-InjectedClassNameType 0x4f6b440 'test<type-parameter-0-0, int>'
      `-*ClassTemplatePartialSpecialization 0x4f6b320 'test'*

Unfortunately I've just started to learn Clang, so I'm not yet able to
improve it.

typedef here has a reference to ClassTemplatePartialSpecializationDecl, and
it has a TemplateTypeParmDecl that has original parameter name "TT". So it
looks like information to print valid code is available in AST.

I have not encountered yet other cases when ASTPrinter emits invalid code.
I hope it is the only one.


2017-10-03 15:06 GMT-07:00 Roman Popov <ripopov at gmail.com>:

> Well... it turned out I actually need to generate valid code from AST.  In
> some cases I need to generate replacements for particular template
> instantiations. But template instantiations exist only in AST, but not in
> the original source code.
> Hopefully I will be able to extend AST printer to work reliably in those
> scenarios;
> 2017-10-03 0:04 GMT-07:00 Roman Popov <ripopov at gmail.com>:
>> Thanks for response!
>> No, I don't really need to mutate the AST.
>> I just had a wrong impression that AST printer is supposed to emit valid
>> code, since it was doing it nicely in most cases. I can certainly grab
>> everything I need to modify from original code.
>> -Roman
>> понедельник, 2 октября 2017 г. пользователь Richard Smith написал:
>> On 29 September 2017 at 13:01, Roman Popov via cfe-dev <
>>> cfe-dev at lists.llvm.org> wrote:
>>>> Hello,
>>>> Is it possible to emit a valid C++ from AST?
>>>> I've tried ASTPrinter in Clang-5.0, but it seems to emit some internal
>>>> Clang representations. For example for template specialization I got:
>>>> template <typename T> struct test<T, int> : sc_core::sc_module {
>>>>     typedef test<type-parameter-0-0, int> this_t;
>>>> ...
>>>> This "type-parameter-0-0"  seem to be some Clang specifics.
>>> We generally try to preserve type sugar, and printing
>>> "type-parameter-0-0" here is undesirable. If you could figure out how we're
>>> losing the type sugar and fix it, we would probably take the fix. However,
>>> while we make a best-effort attempt to produce valid code from the AST
>>> printer, there is in general no guarantee that the output is valid C++; it
>>> is intended for consumption primarily by humans, not by a compiler.
>>> Usually, people asking about the AST printer are trying to perform some
>>> kind of refactoring by mutating the AST and pretty-printing the output. We
>>> do not recommend this approach. Instead, we recommend that you treat the
>>> AST as an immutable representation of the original code, decide on what
>>> transformations you want to perform, and then produce a set of edits to the
>>> original source code that have the desired effect. Clang's Tooling library
>>> provides support utilities for doing this.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171004/0963edde/attachment.html>

More information about the cfe-dev mailing list