1 // RUN: %strip_comments > %t.stripped.cpp 2 // RUN: %clang_cc1 -triple %itanium_abi_triple -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name classtemplate.cpp %t.stripped.cpp > %tmapping 3 // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-CONSTRUCTOR 4 // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-GETTER 5 // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-SETTER 6 // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-INIT-LIST 7 8 template<class TT> 9 class Test { 10 public: 11 enum BaseType { 12 A, C, G, T, Invalid 13 }; 14 const static int BaseCount = 4; 15 double bases[BaseCount]; 16 17 // CHECK-CONSTRUCTOR: _ZN4TestIjEC 18 Test() { } // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:10 -> [[@LINE]]:13 = #0 19 20 // FIXME: It would be nice to emit no-coverage for get, but trying to do this 21 // runs afoul of cases like Test3::unmangleable below. 22 // FIXME-GETTER: _ZNK4TestIjE3get 23 double get(TT position) const { // FIXME-GETTER: File 0, [[@LINE]]:33 -> [[@LINE+2]]:4 = 0 24 return bases[position]; 25 } 26 // CHECK-SETTER: _ZN4TestIjE3set 27 void set(TT position, double value) { // CHECK-SETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = #0 28 bases[position] = value; 29 } 30 }; 31 32 class Test2 { 33 // CHECK-CONSTRUCTOR: _ZN5Test2C 34 Test2() { } // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:11 -> [[@LINE]]:14 = 0 35 // CHECK-GETTER: _ZNK5Test23get 36 double get(unsigned position) const { // CHECK-GETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = 0 37 return 0.0; 38 } 39 }; 40 41 // Test3::unmangleable can't be mangled, since there isn't a complete type for 42 // the __is_final type trait expression. This would cause errors if we try to 43 // emit a no-coverage mapping for the method. 44 template <class T, bool = __is_final(T)> class UninstantiatedClassWithTraits {}; 45 template <class T> class Test3 { 46 void unmangleable(UninstantiatedClassWithTraits<T> x) {} 47 }; 48 49 void abort() __attribute__((noreturn)); 50 51 namespace std { 52 typedef decltype(sizeof(int)) size_t; 53 54 template <typename E> struct initializer_list { 55 const E *p; 56 size_t n; 57 initializer_list(const E *p, size_t n) : p(p), n(n) {} 58 }; 59 60 template <typename F, typename S> struct pair { 61 F f; 62 S s; 63 pair(const F &f, const S &s) : f(f), s(s) {} 64 }; 65 66 struct string { 67 const char *str; 68 string() { abort(); } 69 string(const char *S) : str(S) {} 70 ~string() { abort(); } 71 }; 72 73 template<typename K, typename V> 74 struct map { 75 using T = pair<K, V>; 76 map(initializer_list<T> i, const string &s = string()) {} 77 ~map() { abort(); } 78 }; 79 80 }; // namespace std 81 82 // CHECK-INIT-LIST-LABEL: _Z5Test4v: 83 std::map<int, int> Test4() { // CHECK-INIT-LIST: File 0, [[@LINE]]:28 -> [[@LINE+3]]:2 = #0 84 abort(); 85 return std::map<int, int>{{0, 0}}; // CHECK-INIT-LIST-NEXT: [[@LINE]]:3 -> [[@LINE]]:36 = 0 86 } 87 88 int main() { 89 Test<unsigned> t; 90 t.set(Test<unsigned>::A, 5.5); 91 t.set(Test<unsigned>::T, 5.6); 92 t.set(Test<unsigned>::G, 5.7); 93 t.set(Test<unsigned>::C, 5.8); 94 Test4(); 95 return 0; 96 } 97