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>'}}