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 Boehmevoid f(int) {} // expected-note {{previous definition is here}} f(int)23665da187SMartin Boehmevoid 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 Boehmetemplate <int... Is> void variadic_func_template() { 35665da187SMartin Boehme int [[clang::annotate_type("foo", Is...)]] val; 36665da187SMartin Boehme } f2()37665da187SMartin Boehmeint 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 Boehmevoid 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 Boehmevoid 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