Mercurial > hg > CbC > CbC_llvm
diff clang/test/SemaTemplate/attributes.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 1d019706d866 |
children | c4bab56944e8 |
line wrap: on
line diff
--- a/clang/test/SemaTemplate/attributes.cpp Mon May 25 11:55:54 2020 +0900 +++ b/clang/test/SemaTemplate/attributes.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -63,3 +63,73 @@ // CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations(); void UseAnnotations() { HasAnnotations<int>(); } + +namespace preferred_name { + int x [[clang::preferred_name("frank")]]; // expected-error {{expected a type}} + int y [[clang::preferred_name(int)]]; // expected-warning {{'preferred_name' attribute only applies to class templates}} + struct [[clang::preferred_name(int)]] A; // expected-warning {{'preferred_name' attribute only applies to class templates}} + template<typename T> struct [[clang::preferred_name(int)]] B; // expected-error {{argument 'int' to 'preferred_name' attribute is not a typedef for a specialization of 'B'}} + template<typename T> struct C; + using X = C<int>; // expected-note {{'X' declared here}} + typedef C<float> Y; + using Z = const C<double>; // expected-note {{'Z' declared here}} + template<typename T> struct [[clang::preferred_name(C<int>)]] C; // expected-error {{argument 'C<int>' to 'preferred_name' attribute is not a typedef for a specialization of 'C'}} + template<typename T> struct [[clang::preferred_name(X), clang::preferred_name(Y)]] C; + template<typename T> struct [[clang::preferred_name(const X)]] C; // expected-error {{argument 'const preferred_name::X'}} + template<typename T> struct [[clang::preferred_name(Z)]] C; // expected-error {{argument 'preferred_name::Z' (aka 'const C<double>')}} + template<typename T> struct C {}; + + // CHECK: ClassTemplateDecl {{.*}} <line:[[@LINE-10]]:{{.*}} C + // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition + // CHECK: TemplateArgument type 'int' + // CHECK-NOT: PreferredNameAttr + // CHECK: PreferredNameAttr {{.*}} preferred_name::X + // CHECK-NOT: PreferredNameAttr + // CHECK: CXXRecordDecl + // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition + // CHECK: TemplateArgument type 'float' + // CHECK-NOT: PreferredNameAttr + // CHECK: PreferredNameAttr {{.*}} preferred_name::Y + // CHECK-NOT: PreferredNameAttr + // CHECK: CXXRecordDecl + // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition + // CHECK: TemplateArgument type 'double' + // CHECK-NOT: PreferredNameAttr + // CHECK: CXXRecordDecl + + // Check this doesn't cause us to instantiate the same attribute multiple times. + C<float> *cf1; + C<float> *cf2; + + void f(C<int> a, C<float> b, C<double> c) { + auto p = a; + auto q = b; + auto r = c; + p.f(); // expected-error {{no member named 'f' in 'preferred_name::X'}} + q.f(); // expected-error {{no member named 'f' in 'preferred_name::Y'}} + r.f(); // expected-error {{no member named 'f' in 'preferred_name::C<double>'}} + } + + template<typename T> struct D; + using DInt = D<int>; + template<typename T> struct __attribute__((__preferred_name__(DInt))) D {}; + template struct D<int>; + int use_dint = D<int>().get(); // expected-error {{no member named 'get' in 'preferred_name::DInt'}} + + template<typename T> struct MemberTemplate { + template<typename U> struct Iter; + using iterator = Iter<T>; + using const_iterator = Iter<const T>; + template<typename U> + struct [[clang::preferred_name(iterator), + clang::preferred_name(const_iterator)]] Iter {}; + }; + auto it = MemberTemplate<int>::Iter<const int>(); + int n = it; // expected-error {{no viable conversion from 'preferred_name::MemberTemplate<int>::const_iterator' to 'int'}} + + template<int A, int B, typename ...T> struct Foo; + template<typename ...T> using Bar = Foo<1, 2, T...>; + template<int A, int B, typename ...T> struct [[clang::preferred_name(::preferred_name::Bar<T...>)]] Foo {}; + Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}} +} +::preferred_name::Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}