forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			549 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			549 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 | |
| // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
 | |
| // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers -mconstructor-aliases
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt
 | |
| // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
 | |
| 
 | |
| 
 | |
| #include <typeinfo>
 | |
| 
 | |
| // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 | |
| namespace Test1 {
 | |
| 
 | |
| struct A {
 | |
|   A();
 | |
|   virtual void f();
 | |
|   virtual ~A() { }
 | |
| };
 | |
| 
 | |
| A::A() { }
 | |
| 
 | |
| void f(A* a) {
 | |
|   a->f();
 | |
| };
 | |
| 
 | |
| // CHECK-LABEL: define void @_ZN5Test11gEv
 | |
| // CHECK: call void @_ZN5Test11A1fEv
 | |
| void g() {
 | |
|   A a;
 | |
|   f(&a);
 | |
| }
 | |
| 
 | |
| }
 | |
| 
 | |
| // Test2::A's key function (f) is defined in this translation unit, but when
 | |
| // we're doing codegen for the typeid(A) call, we don't know that yet.
 | |
| // This tests mainly that the typeinfo and typename constants have their linkage
 | |
| // updated correctly.
 | |
| 
 | |
| // CHECK-TEST2: @_ZTSN5Test21AE = constant
 | |
| // CHECK-TEST2: @_ZTIN5Test21AE = constant
 | |
| // CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
 | |
| namespace Test2 {
 | |
|   struct A {
 | |
|     virtual void f();
 | |
|   };
 | |
| 
 | |
|   const std::type_info &g() {
 | |
|     return typeid(A);
 | |
|   };
 | |
| 
 | |
|   void A::f() { }
 | |
| }
 | |
| 
 | |
| // Test that we don't assert on this test.
 | |
| namespace Test3 {
 | |
| 
 | |
| struct A {
 | |
|   virtual void f();
 | |
|   virtual ~A() { }
 | |
| };
 | |
| 
 | |
| struct B : A {
 | |
|   B();
 | |
|   virtual void f();
 | |
| };
 | |
| 
 | |
| B::B() { }
 | |
| 
 | |
| void g(A* a) {
 | |
|   a->f();
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| // PR9114, test that we don't try to instantiate RefPtr<Node>.
 | |
| namespace Test4 {
 | |
| 
 | |
| template <class T> struct RefPtr {
 | |
|   T* p;
 | |
|   ~RefPtr() {
 | |
|     p->deref();
 | |
|   }
 | |
| };
 | |
| 
 | |
| struct A {
 | |
|   virtual ~A();
 | |
| };
 | |
| 
 | |
| struct Node;
 | |
| 
 | |
| struct B : A {
 | |
|   virtual void deref();
 | |
|   RefPtr<Node> m;
 | |
| };
 | |
| 
 | |
| void f() {
 | |
|   RefPtr<B> b;
 | |
| }
 | |
| 
 | |
| }
 | |
| 
 | |
| // PR9130, test that we emit a definition of A::f.
 | |
| // CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv
 | |
| namespace Test5 {
 | |
| 
 | |
| struct A {
 | |
|   virtual void f() { }
 | |
| };
 | |
| 
 | |
| struct B : A { 
 | |
|   virtual ~B();
 | |
| };
 | |
| 
 | |
| B::~B() { }
 | |
| 
 | |
| }
 | |
| 
 | |
| // Check that we don't assert on this test.
 | |
| namespace Test6 {
 | |
| 
 | |
| struct A {
 | |
|   virtual ~A();
 | |
|   int a;
 | |
| };
 | |
| 
 | |
| struct B {
 | |
|   virtual ~B();
 | |
|   int b;
 | |
| };
 | |
| 
 | |
| struct C : A, B { 
 | |
|   C();
 | |
| };
 | |
| 
 | |
| struct D : C {
 | |
|   virtual void f();
 | |
|   D();
 | |
| };
 | |
| 
 | |
| D::D() { }
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace Test7 {
 | |
| 
 | |
| struct c1 {};
 | |
| struct c10 : c1{
 | |
|   virtual void foo ();
 | |
| };
 | |
| struct c11 : c10, c1{
 | |
|   virtual void f6 ();
 | |
| };
 | |
| struct c28 : virtual c11{
 | |
|   void f6 ();
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace Test8 {
 | |
| // CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
 | |
| // vtable for X is not generated because there are no stores here
 | |
| struct X {
 | |
|   X();
 | |
|   virtual void foo();
 | |
| };
 | |
| struct Y : X {
 | |
|   void foo();
 | |
| };
 | |
| 
 | |
| void g(X* p) { p->foo(); }
 | |
| void f() {
 | |
|   Y y;
 | |
|   g(&y);
 | |
|   X x;
 | |
|   g(&x);
 | |
| }
 | |
| 
 | |
| }  // Test8
 | |
| 
 | |
| namespace Test9 {
 | |
| // All virtual functions are outline, so we can assume that it will
 | |
| // be generated in translation unit where foo is defined.
 | |
| // CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
 | |
| // CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
 | |
| struct A {
 | |
|   virtual void foo();
 | |
|   virtual void bar();
 | |
| };
 | |
| void A::bar() {}
 | |
| 
 | |
| struct B : A {
 | |
|   void foo();
 | |
| };
 | |
| 
 | |
| void g() {
 | |
|   A a;
 | |
|   a.foo();
 | |
|   B b;
 | |
|   b.foo();
 | |
| }
 | |
| 
 | |
| }  // Test9
 | |
| 
 | |
| namespace Test10 {
 | |
| 
 | |
| // because A's key function is defined here, vtable is generated in this TU
 | |
| // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 | |
| struct A {
 | |
|   virtual void foo();
 | |
|   virtual void bar();
 | |
| };
 | |
| void A::foo() {}
 | |
| 
 | |
| // Because key function is inline we will generate vtable as linkonce_odr.
 | |
| // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 | |
| struct D : A {
 | |
|   void bar();
 | |
| };
 | |
| inline void D::bar() {}
 | |
| 
 | |
| // Because B has outline all virtual functions, we can refer to them.
 | |
| // CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
 | |
| struct B : A {
 | |
|   void foo();
 | |
|   void bar();
 | |
| };
 | |
| 
 | |
| // C's key function (car) is outline, but C has inline virtual function so we
 | |
| // can't guarantee that we will be able to refer to bar from name
 | |
| // so (at the moment) we can't emit vtable available_externally.
 | |
| // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 | |
| struct C : A {
 | |
|   void bar() {}               // defined in body - not key function
 | |
|   virtual inline void gar();  // inline in body - not key function
 | |
|   virtual void car();
 | |
| };
 | |
| 
 | |
| // no key function, vtable will be generated everywhere it will be used
 | |
| // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
 | |
| 
 | |
| struct E : A {};
 | |
| 
 | |
| void g(A& a) {
 | |
|   a.foo();
 | |
|   a.bar();
 | |
| }
 | |
| 
 | |
| void f() {
 | |
|   A a;
 | |
|   g(a);
 | |
|   B b;
 | |
|   g(b);
 | |
|   C c;
 | |
|   g(c);
 | |
|   D d;
 | |
|   g(d);
 | |
|   E e;
 | |
|   g(e);
 | |
| }
 | |
| 
 | |
| }  // Test10
 | |
| 
 | |
| namespace Test11 {
 | |
| struct D;
 | |
| // Can emit C's vtable available_externally.
 | |
| // CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
 | |
| struct C {
 | |
|   virtual D& operator=(const D&);
 | |
| };
 | |
| 
 | |
| // Can emit D's vtable available_externally.
 | |
| // CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant
 | |
| struct D : C {
 | |
|   virtual void key();
 | |
| };
 | |
| D f();
 | |
| 
 | |
| void g(D& a) {
 | |
|   C c;
 | |
|   c = a;
 | |
|   a.key();
 | |
|   a.key();
 | |
| }
 | |
| void g() {
 | |
|   D d;
 | |
|   d = f();
 | |
|   g(d);
 | |
| }
 | |
| }  // Test 11
 | |
| 
 | |
| namespace Test12 {
 | |
| 
 | |
| // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 | |
| struct A {
 | |
|   virtual void foo();
 | |
|   virtual ~A() {}
 | |
| };
 | |
| // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 | |
| struct B : A {
 | |
|   void foo();
 | |
| };
 | |
| 
 | |
| void g() {
 | |
|   A a;
 | |
|   a.foo();
 | |
|   B b;
 | |
|   b.foo();
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace Test13 {
 | |
| 
 | |
| // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 | |
| // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
 | |
| 
 | |
| struct A {
 | |
|   virtual ~A();
 | |
| };
 | |
| struct B : A {
 | |
|   virtual void f();
 | |
|   void operator delete(void *);
 | |
|   ~B() {}
 | |
| };
 | |
| 
 | |
| void g() {
 | |
|   A *b = new B;
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace Test14 {
 | |
| 
 | |
| // CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
 | |
| struct A {
 | |
|   virtual void f();
 | |
|   void operator delete(void *);
 | |
|   ~A();
 | |
| };
 | |
| 
 | |
| void g() {
 | |
|   A *b = new A;
 | |
|   delete b;
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace Test15 {
 | |
| // In this test D's vtable has two slots for function f(), but uses only one,
 | |
| // so the second slot is set to null.
 | |
| // CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant
 | |
| struct A { virtual void f() {} };
 | |
| struct B : virtual A {};
 | |
| struct C : virtual A {};
 | |
| struct D : B, C {
 | |
|   virtual void g();
 | |
|   void f();
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   D * d = new D;
 | |
|   d->f();
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace Test16 {
 | |
| // S has virtual method that is hidden, because of it we can't
 | |
| // generate available_externally vtable for it.
 | |
| // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 | |
| // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 | |
| 
 | |
| struct S {
 | |
|   __attribute__((visibility("hidden"))) virtual void doStuff();
 | |
| };
 | |
| 
 | |
| struct S2 {
 | |
|   virtual void doStuff();
 | |
|   __attribute__((visibility("hidden"))) void unused();
 | |
| 
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   S *s = new S;
 | |
|   s->doStuff();
 | |
| 
 | |
|   S2 *s2 = new S2;
 | |
|   s2->doStuff();
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace Test17 {
 | |
| // This test checks if we emit vtables opportunistically.
 | |
| // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 | |
| // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev(
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 | |
| 
 | |
| struct A {
 | |
|   virtual void key();
 | |
|   virtual void bar() {}
 | |
| };
 | |
| 
 | |
| // We won't gonna use deleting destructor for this type, which will disallow
 | |
| // emitting vtable as available_externally
 | |
| struct B {
 | |
|   virtual void key();
 | |
|   virtual ~B() {}
 | |
| };
 | |
| 
 | |
| void testcaseA() {
 | |
|   A a;
 | |
|   a.bar(); // this forces to emit definition of bar
 | |
| }
 | |
| 
 | |
| void testcaseB() {
 | |
|   B b; // This only forces emitting of complete object destructor
 | |
| }
 | |
| 
 | |
| } // namespace Test17
 | |
| 
 | |
| namespace Test18 {
 | |
| // Here vtable will be only emitted because it is referenced by assume-load
 | |
| // after the Derived construction.
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE {{.*}} @_ZN6Test184Base3funEv {{.*}} @_ZN6Test184BaseD2Ev {{.*}} @_ZN6Test187DerivedD0Ev
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN6Test184Base3funEv
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant
 | |
| 
 | |
| struct Base {
 | |
|   virtual int fun() { return 42; }
 | |
|   virtual ~Base() { }
 | |
| };
 | |
| 
 | |
| struct Derived : Base {
 | |
|   Derived();
 | |
| };
 | |
| 
 | |
| int foo() {
 | |
|   Derived *der = new Derived();
 | |
|   return der->fun();
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace TestTemplates {
 | |
| 
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev
 | |
| // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
 | |
| 
 | |
| template<class T>
 | |
| struct Template {
 | |
|   Template();
 | |
|   virtual T foo(T val);
 | |
|   // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
 | |
|   virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|   virtual ~Template();
 | |
| };
 | |
| 
 | |
| 
 | |
| struct NonTemplate {
 | |
|   typedef int T;
 | |
|   NonTemplate();
 | |
|   virtual T foo(T val);
 | |
|   // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi
 | |
|   virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|   virtual ~NonTemplate();
 | |
| };
 | |
| 
 | |
| // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev
 | |
| 
 | |
| struct OuterNonTemplate {
 | |
|   template<class T>
 | |
|   struct NestedTemplateInNonTemplate {
 | |
|     NestedTemplateInNonTemplate();
 | |
|     virtual T foo(T val);
 | |
|     // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi
 | |
|     virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|     virtual ~NestedTemplateInNonTemplate();
 | |
|   };
 | |
| 
 | |
|   struct NestedNonTemplateInNonTemplate {
 | |
|     typedef int T;
 | |
|     NestedNonTemplateInNonTemplate();
 | |
|     virtual T foo(T val);
 | |
|     // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi
 | |
|     virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|     virtual ~NestedNonTemplateInNonTemplate();
 | |
|   };
 | |
| };
 | |
| 
 | |
| template<class>
 | |
| struct OuterTemplate {
 | |
|   template<class T>
 | |
|   struct NestedTemplateInTemplate {
 | |
|     NestedTemplateInTemplate();
 | |
|     virtual T foo(T val);
 | |
|     // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi
 | |
|     virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|     virtual ~NestedTemplateInTemplate();
 | |
|   };
 | |
| 
 | |
|   struct NestedNonTemplateInTemplate {
 | |
|     typedef int T;
 | |
|     NestedNonTemplateInTemplate();
 | |
|     virtual T foo(T val);
 | |
|     // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi
 | |
|     virtual T thisShouldBeEmittedToo(T val) { return val; }
 | |
|     virtual ~NestedNonTemplateInTemplate();
 | |
|   };
 | |
| };
 | |
| 
 | |
| template<class T>
 | |
| int use() {
 | |
|   T *ptr = new T();
 | |
|   return ptr->foo(42);
 | |
| }
 | |
| 
 | |
| void test() {
 | |
|   use<Template<int> >();
 | |
|   use<OuterTemplate<long>::NestedTemplateInTemplate<int> >();
 | |
|   use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >();
 | |
| 
 | |
|   use<NonTemplate>();
 | |
|   use<OuterTemplate<long>::NestedNonTemplateInTemplate>();
 | |
|   use<OuterNonTemplate::NestedNonTemplateInNonTemplate>();
 | |
| }
 | |
| }
 |