forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify %s
 | |
| namespace N {
 | |
|   struct Outer {
 | |
|     struct Inner {
 | |
|       template<typename T>
 | |
|       struct InnerTemplate {
 | |
|         struct VeryInner {
 | |
|           typedef T type;
 | |
| 
 | |
|           static enum K1 { K1Val = sizeof(T) } Kind1;
 | |
|           static enum { K2Val = sizeof(T)*2 } Kind2;
 | |
|           enum { K3Val = sizeof(T)*2 } Kind3;
 | |
| 
 | |
|           void foo() {
 | |
|             K1 k1 = K1Val;
 | |
|             Kind1 = K1Val;
 | |
|             Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
 | |
|             Kind3 = K3Val;
 | |
|           }
 | |
| 
 | |
|           struct UeberInner {
 | |
|             void bar() {
 | |
|               K1 k1 = K1Val;
 | |
|               Kind1 = K1Val;
 | |
|               Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
 | |
| 
 | |
|               InnerTemplate t;
 | |
|               InnerTemplate<type> t2;
 | |
|             }
 | |
|           };
 | |
|         };
 | |
|       };
 | |
|     };
 | |
|   };
 | |
| }
 | |
| 
 | |
| typedef int INT;
 | |
| template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
 | |
| template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
 | |
| 
 | |
| namespace N2 {
 | |
|   struct Outer2 {
 | |
|     template<typename T, typename U = T>
 | |
|     struct Inner {
 | |
|       void foo() {
 | |
|         enum { K1Val = sizeof(T) } k1;
 | |
|         enum K2 { K2Val = sizeof(T)*2 } k2a;
 | |
| 
 | |
|         K2 k2b = K2Val;
 | |
| 
 | |
|         struct S { T x, y; } s1;
 | |
|         struct { U x, y; } s2;
 | |
|         s1.x = s2.x; // expected-error{{incompatible}}
 | |
| 
 | |
|         typedef T type;
 | |
|         type t2 = s1.x;
 | |
| 
 | |
|         typedef struct { T z; } type2;
 | |
|         type2 t3 = { s1.x };
 | |
| 
 | |
|         Inner i1;
 | |
|         i1.foo();
 | |
|         Inner<T> i2;
 | |
|         i2.foo();
 | |
|       }
 | |
|     };
 | |
|   };
 | |
| }
 | |
| 
 | |
| template struct N2::Outer2::Inner<float>;
 | |
| template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
 | |
| 
 | |
| // Test dependent pointer-to-member expressions.
 | |
| template<typename T>
 | |
| struct smart_ptr {
 | |
|   struct safe_bool {
 | |
|     int member;
 | |
|   };
 | |
|   
 | |
|   operator int safe_bool::*() const { 
 | |
|     return ptr? &safe_bool::member : 0;
 | |
|   }
 | |
|   
 | |
|   T* ptr;
 | |
| };
 | |
| 
 | |
| void test_smart_ptr(smart_ptr<int> p) {
 | |
|   if (p) { }
 | |
| }
 | |
| 
 | |
| // PR5517
 | |
| namespace test0 {
 | |
|   template <int K> struct X {
 | |
|     X() { extern void x(); }
 | |
|   };
 | |
|   void g() { X<2>(); }
 | |
| }
 | |
| 
 | |
| // <rdar://problem/8302161>
 | |
| namespace test1 {
 | |
|   template <typename T> void f(T const &t) {
 | |
|     union { char c; T t_; };
 | |
|     c = 'a'; // <- this shouldn't silently fail to instantiate
 | |
|     T::foo(); // expected-error {{has no members}}
 | |
|   }
 | |
|   template void f(int const &); // expected-note {{requested here}}
 | |
| }
 | |
| 
 | |
| namespace test2 {
 | |
|   template<typename T> void f() {
 | |
|     T::error; // expected-error {{no member}}
 | |
|   }
 | |
|   void g() {
 | |
|     // This counts as an odr-use, so should trigger the instantiation of f<int>.
 | |
|     (void)&f<int>; // expected-note {{here}}
 | |
|   }
 | |
| }
 |