1 // RUN: %clang_cc1 %s -DUSEIT -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s 2 3 // Test with decls and template defs in pch, and just use in .cpp 4 // RUN: %clang_cc1 %s -DTMPL_DEF_IN_HEADER -triple %itanium_abi_triple -emit-pch -o %t 5 // RUN: %clang_cc1 %s -DTMPL_DEF_IN_HEADER -DUSEIT -triple %itanium_abi_triple -include-pch %t -emit-llvm -o - | FileCheck %s 6 7 // Test with A in pch, and B and C in main 8 // Test with just decls in pch, and template defs and use in .cpp 9 // RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-pch -o %t 10 // RUN: %clang_cc1 %s -DUSEIT -triple %itanium_abi_triple -include-pch %t -emit-llvm -o - | FileCheck %s 11 12 #ifndef HEADER 13 #define HEADER 14 template < typename T, int N = 0 > class TmplWithArray { 15 public: 16 virtual T& operator [] (int idx); 17 virtual T& func1 (int idx); 18 virtual T& func2 (int idx); 19 T ar[N+1]; 20 }; 21 struct Wrapper { 22 TmplWithArray<bool, 10> data; 23 bool indexIt(int a) { 24 if (a > 6) return data[a] ; // Should devirtualize 25 if (a > 4) return data.func1(a); // Should devirtualize 26 return data.func2(a); // Should devirtualize 27 } 28 }; 29 30 #ifdef TMPL_DEF_IN_HEADER 31 template <typename T, int N> T& TmplWithArray<T, N >::operator[](int idx) { 32 return ar[idx]; 33 } 34 template <typename T, int N> T& TmplWithArray<T, N >::func1(int idx) { 35 return ar[idx]; 36 } 37 #endif // TMPL_DEF_IN_HEADER 38 #endif // HEADER 39 40 #ifdef USEIT 41 #ifndef TMPL_DEF_IN_HEADER 42 template <typename T, int N> T& TmplWithArray<T, N >::operator[](int idx) { 43 return ar[idx]; 44 } 45 template <typename T, int N> T& TmplWithArray<T, N >::func1(int idx) { 46 return ar[idx]; 47 } 48 #endif // !TMPL_DEF_IN_HEADER 49 extern Wrapper ew; 50 bool stuff(int p) 51 { 52 return ew.indexIt(p); 53 } 54 #endif 55 56 // CHECK-DAG: call {{.*}} @_ZN13TmplWithArrayIbLi10EEixEi 57 // CHECK-DAG: call {{.*}} @_ZN13TmplWithArrayIbLi10EE5func1Ei 58 // CHECK-DAG: call {{.*}} @_ZN13TmplWithArrayIbLi10EE5func2Ei 59 60