llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.82k stars 11k forks source link

`-ast-dump=json` doesn't provide the contents of `clang::annotate` #61299

Open brevzin opened 1 year ago

brevzin commented 1 year ago

Consider this simple example:

struct Class {
    [[clang::annotate("meow")]] int member;
};

If I do the normal ast-dump, you can see the type Class, with the member int, with the attached annotation meow:

$ clang -Xclang -ast-dump -fsyntax-only -c foo.cxx
TranslationUnitDecl 0x97518d8 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x9752140 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x9751ea0 '__int128'
|-TypedefDecl 0x97521b0 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x9751ec0 'unsigned __int128'
|-TypedefDecl 0x9752528 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0x97522a0 '__NSConstantString_tag'
|   `-CXXRecord 0x9752208 '__NSConstantString_tag'
|-TypedefDecl 0x97525c0 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x9752580 'char *'
|   `-BuiltinType 0x9751980 'char'
|-TypedefDecl 0x9797948 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag[1]'
| `-ConstantArrayType 0x97978f0 '__va_list_tag[1]' 1
|   `-RecordType 0x97526b0 '__va_list_tag'
|     `-CXXRecord 0x9752618 '__va_list_tag'
`-CXXRecordDecl 0x97979a0 <foo.cxx:1:1, line:3:1> line:1:8 struct Class definition
  |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
  | |-DefaultConstructor exists trivial needs_implicit
  | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveAssignment exists simple trivial needs_implicit
  | `-Destructor simple irrelevant trivial needs_implicit
  |-CXXRecordDecl 0x9797ab8 <col:1, col:8> col:8 implicit struct Class
  `-FieldDecl 0x9797c00 <line:2:33, col:37> col:37 member 'int'
    `-AnnotateAttr 0x9797c50 <col:7, col:29> "meow"

If I do -ast-dump=json, I get a JSON file that looks like this. It is 298 lines long, so I'll just snip the relevant part: what we get for member:

          "name": "member",
          "type": {
            "qualType": "int"
          },
          "inner": [
            {
              "id": "0x9797c60",
              "kind": "AnnotateAttr",
              "range": {
                "begin": {
                  "offset": 21,
                  "col": 7,
                  "tokLen": 5
                },
                "end": {
                  "offset": 43,
                  "col": 29,
                  "tokLen": 1
                }
              }
            }
          ]

meow does not appear here. I just get the range of tokens with their contents. This is correct (the attribute is is col 7:29 - that's all of clang::annotate("meow"), and walking the tree up I can get that it's on line 2), but it'd be nicer if I additionally got the actual annotate contents: "meow".

AaronBallman commented 1 year ago

We use clang-tblgen to generate the code to handle dumping text nodes but we do not have the same thing for dumping JSON nodes. I I think it would be a reasonable feature to support, however.

https://github.com/llvm/llvm-project/blob/5348a25377652c5e32f9a85754da7231cb9bf9f6/clang/utils/TableGen/ClangAttrEmitter.cpp#L4473 is where the logic lives for dumping textual nodes, and we'd need something similar for JSON.

This isn't quite good-first-issue material because it involves tablegen, but it is a good first issue for anyone wanting to learn more about Clang's tablegen.