xref: /llvm-project/clang/test/SemaCXX/annotate-type.cpp (revision 8c7b64b5ae2a09027c38db969a04fc9ddd0cd6bb)
1665da187SMartin Boehme // RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -fcxx-exceptions -verify
2665da187SMartin Boehme 
3665da187SMartin Boehme struct S1 {
4665da187SMartin Boehme   void f() [[clang::annotate_type("foo")]];
5*8c7b64b5SMartin Boehme   [[clang::annotate_type("foo")]] void g(); // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
6665da187SMartin Boehme };
7665da187SMartin Boehme 
8665da187SMartin Boehme template <typename T1, typename T2> struct is_same {
9665da187SMartin Boehme   static constexpr bool value = false;
10665da187SMartin Boehme };
11665da187SMartin Boehme 
12665da187SMartin Boehme template <typename T1> struct is_same<T1, T1> {
13665da187SMartin Boehme   static constexpr bool value = true;
14665da187SMartin Boehme };
15665da187SMartin Boehme 
16665da187SMartin Boehme static_assert(is_same<int, int [[clang::annotate_type("foo")]]>::value);
17665da187SMartin Boehme static_assert(is_same<int [[clang::annotate_type("foo")]],
18665da187SMartin Boehme                       int [[clang::annotate_type("bar")]]>::value);
19665da187SMartin Boehme static_assert(is_same<int *, int *[[clang::annotate_type("foo")]]>::value);
20665da187SMartin Boehme 
21665da187SMartin Boehme // Cannot overload on types that only differ by `annotate_type` attribute.
f(int)22665da187SMartin Boehme void f(int) {} // expected-note {{previous definition is here}}
f(int)23665da187SMartin Boehme void f(int [[clang::annotate_type("foo")]]) {} // expected-error {{redefinition of 'f'}}
24665da187SMartin Boehme 
25665da187SMartin Boehme // Cannot specialize on types that only differ by `annotate_type` attribute.
26665da187SMartin Boehme template <class T> struct S2 {};
27665da187SMartin Boehme 
28665da187SMartin Boehme template <> struct S2<int> {}; // expected-note {{previous definition is here}}
29665da187SMartin Boehme 
30665da187SMartin Boehme template <>
31665da187SMartin Boehme struct S2<int [[clang::annotate_type("foo")]]> {}; // expected-error {{redefinition of 'S2<int>'}}
32665da187SMartin Boehme 
33665da187SMartin Boehme // Test that the attribute supports parameter pack expansion.
variadic_func_template()34665da187SMartin Boehme template <int... Is> void variadic_func_template() {
35665da187SMartin Boehme   int [[clang::annotate_type("foo", Is...)]] val;
36665da187SMartin Boehme }
f2()37665da187SMartin Boehme int f2() { variadic_func_template<1, 2, 3>(); }
38665da187SMartin Boehme 
39665da187SMartin Boehme // Make sure we correctly diagnose wrong number of arguments for
40665da187SMartin Boehme // [[clang::annotate_type]] inside a template argument.
41665da187SMartin Boehme template <typename Ty> void func_template();
f3()42665da187SMartin Boehme void f3() {
43665da187SMartin Boehme   func_template<int [[clang::annotate_type()]]>(); // expected-error {{'annotate_type' attribute takes at least 1 argument}}
44665da187SMartin Boehme }
45665da187SMartin Boehme 
46665da187SMartin Boehme // More error cases: Prohibit adding the attribute to declarations.
47665da187SMartin Boehme // Different declarations hit different code paths, so they need separate tests.
48*8c7b64b5SMartin Boehme namespace [[clang::annotate_type("foo")]] my_namespace {} // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
49*8c7b64b5SMartin Boehme struct [[clang::annotate_type("foo")]] S3; // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
50*8c7b64b5SMartin Boehme struct [[clang::annotate_type("foo")]] S3{ // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
51*8c7b64b5SMartin Boehme   [[clang::annotate_type("foo")]] int member; // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
52665da187SMartin Boehme };
f4()53665da187SMartin Boehme void f4() {
54*8c7b64b5SMartin Boehme   for ([[clang::annotate_type("foo")]] int i = 0; i < 42; ++i) {} // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
55*8c7b64b5SMartin Boehme   for (; [[clang::annotate_type("foo")]] bool b = false;) {} // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
56*8c7b64b5SMartin Boehme   while ([[clang::annotate_type("foo")]] bool b = false) {} // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
57*8c7b64b5SMartin Boehme   if ([[clang::annotate_type("foo")]] bool b = false) {} // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
58665da187SMartin Boehme   try {
59*8c7b64b5SMartin Boehme   } catch ([[clang::annotate_type("foo")]] int i) { // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
60665da187SMartin Boehme   }
61665da187SMartin Boehme }
62665da187SMartin Boehme template <class T>
63*8c7b64b5SMartin Boehme [[clang::annotate_type("foo")]] T var_template; // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
64*8c7b64b5SMartin Boehme [[clang::annotate_type("foo")]] extern "C" int extern_c_func(); // expected-error {{an attribute list cannot appear here}}
65*8c7b64b5SMartin Boehme extern "C" [[clang::annotate_type("foo")]] int extern_c_func(); // expected-error {{'annotate_type' attribute cannot be applied to a declaration}}
66