Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 namespace N {
      3   struct Outer {
      4     struct Inner {
      5       template<typename T>
      6       struct InnerTemplate {
      7         struct VeryInner {
      8           typedef T type;
      9 
     10           static enum K1 { K1Val = sizeof(T) } Kind1;
     11           static enum { K2Val = sizeof(T)*2 } Kind2;
     12           enum { K3Val = sizeof(T)*2 } Kind3;
     13 
     14           void foo() {
     15             K1 k1 = K1Val;
     16             Kind1 = K1Val;
     17             Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
     18             Kind3 = K3Val;
     19           }
     20 
     21           struct UeberInner {
     22             void bar() {
     23               K1 k1 = K1Val;
     24               Kind1 = K1Val;
     25               Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
     26 
     27               InnerTemplate t;
     28               InnerTemplate<type> t2;
     29             }
     30           };
     31         };
     32       };
     33     };
     34   };
     35 }
     36 
     37 typedef int INT;
     38 template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
     39 template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
     40 
     41 namespace N2 {
     42   struct Outer2 {
     43     template<typename T, typename U = T>
     44     struct Inner {
     45       void foo() {
     46         enum { K1Val = sizeof(T) } k1;
     47         enum K2 { K2Val = sizeof(T)*2 } k2a;
     48 
     49         K2 k2b = K2Val;
     50 
     51         struct S { T x, y; } s1;
     52         struct { U x, y; } s2;
     53         s1.x = s2.x; // expected-error{{incompatible}}
     54 
     55         typedef T type;
     56         type t2 = s1.x;
     57 
     58         typedef struct { T z; } type2;
     59         type2 t3 = { s1.x };
     60 
     61         Inner i1;
     62         i1.foo();
     63         Inner<T> i2;
     64         i2.foo();
     65       }
     66     };
     67   };
     68 }
     69 
     70 template struct N2::Outer2::Inner<float>;
     71 template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
     72 
     73 // Test dependent pointer-to-member expressions.
     74 template<typename T>
     75 struct smart_ptr {
     76   struct safe_bool {
     77     int member;
     78   };
     79 
     80   operator int safe_bool::*() const {
     81     return ptr? &safe_bool::member : 0;
     82   }
     83 
     84   T* ptr;
     85 };
     86 
     87 void test_smart_ptr(smart_ptr<int> p) {
     88   if (p) { }
     89 }
     90 
     91 // PR5517
     92 namespace test0 {
     93   template <int K> struct X {
     94     X() { extern void x(); }
     95   };
     96   void g() { X<2>(); }
     97 }
     98 
     99 // <rdar://problem/8302161>
    100 namespace test1 {
    101   template <typename T> void f(T const &t) {
    102     union { char c; T t_; };
    103     c = 'a'; // <- this shouldn't silently fail to instantiate
    104     T::foo(); // expected-error {{has no members}}
    105   }
    106   template void f(int const &); // expected-note {{requested here}}
    107 }
    108 
    109 namespace test2 {
    110   template<typename T> void f() {
    111     T::error; // expected-error {{no member}}
    112   }
    113   void g() {
    114     // This counts as an odr-use, so should trigger the instantiation of f<int>.
    115     (void)&f<int>; // expected-note {{here}}
    116   }
    117 }
    118