yonghong-song added a comment.

In D110127#3012215 <https://reviews.llvm.org/D110127#3012215>, @aaron.ballman 
wrote:

>> First, to build linux kernel with btf_tag annotated user pointer, we have
>>
>> #define __user __attribute__((btf_tag("user")))
>> and the linux kernel contains code like below ([2])
>>
>> typedef __signalfn_t __user *__sighandler_t;
>> and the user attribute applies to typedef type sighandler_t.
>> So clang needs to support btf_tag attribute with typedef type
>> to avoid compilation error.
>
> I want to make sure we're clear on the semantics here. That defines 
> `__sighandler_t` to be the type `__signalfn_t __user *`, so you expect this 
> to annotate the type, not the declaration of the typedef. So this is about 
> allowing `btf_tag` on types in addition to declarations?

This is a good question and below are some examples:
[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef __tag1 unsigned * __u;
__u u;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -TypedefDecl 0x8279c00 <<invalid sloc>> <invalid sloc> implicit 
__builtin_va_list 'struct __va_list_tag [1]' |
| `-ConstantArrayType 0x8234e30 'struct __va_list_tag [1]' 1                    
                               |
| `-RecordType 0x8234c70 'struct __va_list_tag'                                 
                               |
| `-Record 0x8234be8 '__va_list_tag'                                            
                               |
| -TypedefDecl 0x8279d00 <t.c:2:1, col:27> col:27 referenced __u 'unsigned int 
*'                              |
|                                                                               
                               | -PointerType 0x8279cc0 'unsigned int *' |
|                                                                               
                               | `-BuiltinType 0x8234040 'unsigned int'  |
| `-BTFTagAttr 0x8279d58 <line:1:31, col:45> "tag1"                             
                               |
|

`-VarDecl 0x8279df0 <line:3:1, col:5> col:5 u '__u':'unsigned int *'

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef unsigned __tag1 * __u;
__u u;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -TypedefDecl 0x8279c00 <<invalid sloc>> <invalid sloc> implicit 
__builtin_va_list 'struct __va_list_tag [1]' |
| `-ConstantArrayType 0x8234e30 'struct __va_list_tag [1]' 1                    
                               |
| `-RecordType 0x8234c70 'struct __va_list_tag'                                 
                               |
| `-Record 0x8234be8 '__va_list_tag'                                            
                               |
| -TypedefDecl 0x8279d00 <t.c:2:1, col:27> col:27 referenced __u 'unsigned int 
*'                              |
|                                                                               
                               | -PointerType 0x8279cc0 'unsigned int *' |
|                                                                               
                               | `-BuiltinType 0x8234040 'unsigned int'  |
| `-BTFTagAttr 0x8279d58 <line:1:31, col:45> "tag1"                             
                               |
|

`-VarDecl 0x8279df0 <line:3:1, col:5> col:5 u '__u':'unsigned int *'

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef unsigned * __tag1 __u;
__u u;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -TypedefDecl 0x8279c00 <<invalid sloc>> <invalid sloc> implicit 
__builtin_va_list 'struct __va_list_tag [1]' |
| `-ConstantArrayType 0x8234e30 'struct __va_list_tag [1]' 1                    
                               |
| `-RecordType 0x8234c70 'struct __va_list_tag'                                 
                               |
| `-Record 0x8234be8 '__va_list_tag'                                            
                               |
| -TypedefDecl 0x8279d00 <t.c:2:1, col:27> col:27 referenced __u 'unsigned int 
*'                              |
|                                                                               
                               | -PointerType 0x8279cc0 'unsigned int *' |
|                                                                               
                               | `-BuiltinType 0x8234040 'unsigned int'  |
| `-BTFTagAttr 0x8279d58 <line:1:31, col:45> "tag1"                             
                               |
|

`-VarDecl 0x8279df0 <line:3:1, col:5> col:5 u '__u':'unsigned int *'

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef unsigned * __u __tag1;
__u u;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -TypedefDecl 0x8279c00 <<invalid sloc>> <invalid sloc> implicit 
__builtin_va_list 'struct __va_list_tag [1]' |
| `-ConstantArrayType 0x8234e30 'struct __va_list_tag [1]' 1                    
                               |
| `-RecordType 0x8234c70 'struct __va_list_tag'                                 
                               |
| `-Record 0x8234be8 '__va_list_tag'                                            
                               |
| -TypedefDecl 0x8279d00 <t.c:2:1, col:20> col:20 referenced __u 'unsigned int 
*'                              |
|                                                                               
                               | -PointerType 0x8279cc0 'unsigned int *' |
|                                                                               
                               | `-BuiltinType 0x8234040 'unsigned int'  |
| `-BTFTagAttr 0x8279d58 <line:1:31, col:45> "tag1"                             
                               |
|

`-VarDecl 0x8279df0 <line:3:1, col:5> col:5 u '__u':'unsigned int *'

You can see that it doesn't matter where the attribute is placed, the attribute 
is always attached to the typedef.
I think the reason is for declarations, we only allow the btf_tag attribute to 
be placed for record, field, var, func, typedef,
and "unsigned *" does not qualify, so the attribute is applied to typedef.

See below example for structure, the attribute can be applied to either 
structure or to typedef.

>> typedef struct { ... } target_type __btf_tag
>
> Similar here -- this applies the __btf_tag to the type, not to the 
> declaration of the typedef, right?

In the above case, it actually applied to the typedef. See below example.

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef __tag1 struct { int a; } __s;
__s a;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -RecordDecl 0x8279cb8 <t.c:2:16, col:32> col:16 struct definition             
  |
| `-FieldDecl 0x8279d78 <col:25, col:29> col:29 a 'int'                         
  |
| -TypedefDecl 0x8279e28 <col:1, col:34> col:34 referenced __s 'struct 
__s':'__s' |
|                                                                               
  | -ElaboratedType 0x8279dd0 'struct __s' sugar |
|                                                                               
  | `-RecordType 0x8279d40 '__s'                 |
|                                                                               
  | `-Record 0x8279cb8 ''                        |
| `-BTFTagAttr 0x8279e80 <line:1:31, col:45> "tag1"                             
  |
|

`-VarDecl 0x8279f30 <line:3:1, col:5> col:5 a '__s':'__s'

the attribute is attached to typedef.

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef struct __tag1 { int a; } __s;
__s a;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -RecordDecl 0x8279cb8 <t.c:2:9, col:32> col:9 struct definition               
  |
|                                                                               
  | -BTFTagAttr 0x8279d60 <line:1:31, col:45> "tag1" |
| `-FieldDecl 0x8279de0 <line:2:25, col:29> col:29 a 'int'                      
  |
| -TypedefDecl 0x8279e88 <col:1, col:34> col:34 referenced __s 'struct 
__s':'__s' |
| `-ElaboratedType 0x8279e30 'struct __s' sugar                                 
  |
| `-RecordType 0x8279d40 '__s'                                                  
  |
| `-Record 0x8279cb8 ''                                                         
  |
|

`-VarDecl 0x8279f30 <line:3:1, col:5> col:5 a '__s':'__s'

The attribute is attached to the structure.

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef struct { int a; } __tag1 __s;
__s a;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -RecordDecl 0x8279c58 <t.c:2:9, col:25> col:9 struct definition               
  |
|                                                                               
  | -BTFTagAttr 0x8279dc8 <line:1:31, col:45> "tag1" |
| `-FieldDecl 0x8279d18 <line:2:18, col:22> col:22 a 'int'                      
  |
| -TypedefDecl 0x8279e88 <col:1, col:34> col:34 referenced __s 'struct 
__s':'__s' |
| `-ElaboratedType 0x8279e30 'struct __s' sugar                                 
  |
| `-RecordType 0x8279ce0 '__s'                                                  
  |
| `-Record 0x8279c58 ''                                                         
  |
|

`-VarDecl 0x8279f30 <line:3:1, col:5> col:5 a '__s':'__s'

the attribute is attached to the structure.

[$ ~/work/tests/llvm/btf_tag] cat t.c
#define __tag1 __attribute__((btf_tag("tag1")))
typedef struct { int a; } __s __tag1;
__s a;
[$ ~/work/tests/llvm/btf_tag] clang -Xclang -ast-dump -c t.c
...

| -RecordDecl 0x8279c58 <t.c:2:9, col:25> col:9 struct definition               
  |
| `-FieldDecl 0x8279d18 <col:18, col:22> col:22 a 'int'                         
  |
| -TypedefDecl 0x8279e28 <col:1, col:27> col:27 referenced __s 'struct 
__s':'__s' |
|                                                                               
  | -ElaboratedType 0x8279dd0 'struct __s' sugar |
|                                                                               
  | `-RecordType 0x8279ce0 '__s'                 |
|                                                                               
  | `-Record 0x8279c58 ''                        |
| `-BTFTagAttr 0x8279e80 <line:1:31, col:45> "tag1"                             
  |
|

`-VarDecl 0x8279f30 <line:3:1, col:5> col:5 a '__s':'__s'

The attribute is attached to typedef.

> I'm asking because this raises other questions. For example:
>
>   void func(int i);
>   void func(int __attribute__((btf_tag("__user"))) i);
>
> Is the second a valid redeclaration of the first? Additionally:

This should be okay as btf_tag is accumulative attribute.

>   __attribute__((overloadable)) void func(int i) { puts("one"); }
>   __attribute__((overloadable)) void func(int 
> __attribute__((btf_tag("__user"))) i) { puts("two"); }
>
> Is this a valid overload set because of the type attribute? Along the same 
> lines, does adding this attribute to the type cause any ABI differences in 
> how the type is passed?

btf_tag is for C only so overload function case won't happen.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110127/new/

https://reviews.llvm.org/D110127

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to