[clang] [clang][AST] Fix printing `TagDecl`s. (PR #69971)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 30 12:38:33 PDT 2023


isuckatcs wrote:

It seems I found one more issue.

```c++
struct A {
  int x;
};

struct Foo {
  struct obj {
    int x;
  } *(*next)(struct A *q);
};
```
```c++
error: 'Foo::obj' cannot be defined in the result type of a function
    6 |   struct obj {
      |          ^
struct A {
    int x;
};
struct Foo {
    struct obj {
        int x;
    } *(*next)(struct A {
        int x;
    } *);
};
```
During the printing of the AST we either print every tag definition or none. We have no way to limit which one should get printed and which one shouldn't. The input snippet is already not a valid c++ code, so I'm not sure if we care about it or not.

> I think we should always print attributes, but only print the ones that are not inherited (that is, the ones that are written on that declaration).

We have 2 different printers that have different rules. `DeclPrinter` always prints the attributes, `TypePriner` doesn't. In `TypePrinter` if we want to print the definition, we invoke `DeclPrinter` to do so, which will print the attributes. However C++ allows you to write functions like `void foo(struct __attribute__((aligned(16))) A *q);` in which case the attribute should indeed be printed by `TypePrinter` but it's not.

On the other hand it would also change how the AST is printed, which I think is not something we want.
```c++
template <typename T> struct my_template {};

struct alignas(8) A {};

my_template<A> my_template_instance;
```
```
`-VarDecl ... my_template_instance 'my_template<A>' callinit
  `-CXXConstructExpr ... 'my_template<A>' 'void () noexcept'
```
```
`-VarDecl ... my_template_instance 'my_template< alignas(8) A>':'my_template< alignas(8) A>' callinit
  `-CXXConstructExpr ... 'my_template< alignas(8) A>':'my_template< alignas(8) A>' 'void () noexcept'
```

https://github.com/llvm/llvm-project/pull/69971


More information about the cfe-commits mailing list