yonghong-song created this revision. yonghong-song added reviewers: ast, aaron.ballman. Herald added a project: All. yonghong-song requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When running bcc tool execsnoop ([1]) which is built with latest llvm, I hit the following error: $ sudo ./execsnoop.py /virtual/main.c:99:157: error: expected ')' data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct task_struct btf_type_tag(rcu)*) _val; __builtin_memset(&_val, 0, sizeof(_val)); ^ bpf_probe_read(&_val, sizeof(_val), (void *)&task->real_parent); _val; })->tgid); _val; }); The failure reason is due to that the bcc rewriter printed type like struct task_struct btf_type_tag(rcu)* where the compiler cannot recognize what 'btf_type_tag(rcu)' is. The above type is printed in [2] by UnaryOperator->getType().getAsString() (from clang) in function ProbeVisitor::VisitUnaryOperator. The original source type looks like ([3]) struct task_struct { ... struct task_struct __rcu *real_parent; ... } where '__rcu' is a macro expanding to '__attribute__((btf_type_tag("rcu")))'. Let us print btf_type_tag properly in clang so bcc tools and broader type printing will work properly. With this patch, the above rewrited source code looks like data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct task_struct __attribute__((btf_type_tag("rcu")))*) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&task->real_parent); _val; })->tgid); _val; }); and execsnoop.py tool can run properly. [1] https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py [2] https://github.com/iovisor/bcc/blob/master/src/cc/frontends/clang/b_frontend_action.cc [3] https://github.com/torvalds/linux/blob/master/include/linux/sched.h Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D150017 Files: clang/lib/AST/TypePrinter.cpp clang/test/AST/ast-dump-bpf-attr.c clang/test/Sema/attr-btf_type_tag.c clang/test/SemaCXX/sugar-common-types.cpp Index: clang/test/SemaCXX/sugar-common-types.cpp =================================================================== --- clang/test/SemaCXX/sugar-common-types.cpp +++ clang/test/SemaCXX/sugar-common-types.cpp @@ -95,7 +95,7 @@ using SBTF3 = ::SS1 [[clang::btf_type_tag("2")]]; N t21 = 0 ? (SBTF1){} : (SBTF3){}; // expected-error {{from 'SS1'}} -N t22 = 0 ? (SBTF1){} : (SBTF2){}; // expected-error {{from 'SS1 btf_type_tag(1)' (aka 'SS1')}} +N t22 = 0 ? (SBTF1){} : (SBTF2){}; // expected-error {{from 'SS1 __attribute__((btf_type_tag("1")))' (aka 'SS1')}} using QX = const SB1 *; using QY = const ::SB1 *; Index: clang/test/Sema/attr-btf_type_tag.c =================================================================== --- clang/test/Sema/attr-btf_type_tag.c +++ clang/test/Sema/attr-btf_type_tag.c @@ -28,8 +28,8 @@ int g1 = _Generic((int *)0, int __tag1 *: 0); int g2 = _Generic((int __tag1 *)0, int *: 0); int g3 = _Generic(0, - int __tag1 * : 0, // expected-note {{compatible type 'int btf_type_tag(tag1)*' (aka 'int *') specified here}} - int * : 0, // expected-error {{type 'int *' in generic association compatible with previously specified type 'int btf_type_tag(tag1)*' (aka 'int *')}} + int __tag1 * : 0, // expected-note {{compatible type 'int __attribute__((btf_type_tag("tag1")))*' (aka 'int *') specified here}} + int * : 0, // expected-error {{type 'int *' in generic association compatible with previously specified type 'int __attribute__((btf_type_tag("tag1")))*' (aka 'int *')}} default : 0); // The btf_type_tag attribute will be ignored during overloadable type matching Index: clang/test/AST/ast-dump-bpf-attr.c =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-bpf-attr.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple bpf-pc-linux-gnu -ast-dump %s \ +// RUN: | FileCheck --strict-whitespace %s + +int __attribute__((btf_type_tag("rcu"))) * g; +// CHECK: VarDecl{{.*}}g 'int __attribute__((btf_type_tag("rcu")))*' Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ clang/lib/AST/TypePrinter.cpp @@ -1845,7 +1845,7 @@ void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T, raw_ostream &OS) { printBefore(T->getWrappedType(), OS); - OS << " btf_type_tag(" << T->getAttr()->getBTFTypeTag() << ")"; + OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))"; } void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
Index: clang/test/SemaCXX/sugar-common-types.cpp =================================================================== --- clang/test/SemaCXX/sugar-common-types.cpp +++ clang/test/SemaCXX/sugar-common-types.cpp @@ -95,7 +95,7 @@ using SBTF3 = ::SS1 [[clang::btf_type_tag("2")]]; N t21 = 0 ? (SBTF1){} : (SBTF3){}; // expected-error {{from 'SS1'}} -N t22 = 0 ? (SBTF1){} : (SBTF2){}; // expected-error {{from 'SS1 btf_type_tag(1)' (aka 'SS1')}} +N t22 = 0 ? (SBTF1){} : (SBTF2){}; // expected-error {{from 'SS1 __attribute__((btf_type_tag("1")))' (aka 'SS1')}} using QX = const SB1 *; using QY = const ::SB1 *; Index: clang/test/Sema/attr-btf_type_tag.c =================================================================== --- clang/test/Sema/attr-btf_type_tag.c +++ clang/test/Sema/attr-btf_type_tag.c @@ -28,8 +28,8 @@ int g1 = _Generic((int *)0, int __tag1 *: 0); int g2 = _Generic((int __tag1 *)0, int *: 0); int g3 = _Generic(0, - int __tag1 * : 0, // expected-note {{compatible type 'int btf_type_tag(tag1)*' (aka 'int *') specified here}} - int * : 0, // expected-error {{type 'int *' in generic association compatible with previously specified type 'int btf_type_tag(tag1)*' (aka 'int *')}} + int __tag1 * : 0, // expected-note {{compatible type 'int __attribute__((btf_type_tag("tag1")))*' (aka 'int *') specified here}} + int * : 0, // expected-error {{type 'int *' in generic association compatible with previously specified type 'int __attribute__((btf_type_tag("tag1")))*' (aka 'int *')}} default : 0); // The btf_type_tag attribute will be ignored during overloadable type matching Index: clang/test/AST/ast-dump-bpf-attr.c =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-bpf-attr.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple bpf-pc-linux-gnu -ast-dump %s \ +// RUN: | FileCheck --strict-whitespace %s + +int __attribute__((btf_type_tag("rcu"))) * g; +// CHECK: VarDecl{{.*}}g 'int __attribute__((btf_type_tag("rcu")))*' Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ clang/lib/AST/TypePrinter.cpp @@ -1845,7 +1845,7 @@ void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T, raw_ostream &OS) { printBefore(T->getWrappedType(), OS); - OS << " btf_type_tag(" << T->getAttr()->getBTFTypeTag() << ")"; + OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))"; } void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits