xref: /llvm-project/clang/test/CoverageMapping/classtemplate.cpp (revision 9783e2098800b954c55ae598a1ce5c4b93444fc0)
19caa3fbeSZequan Wu // RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple %itanium_abi_triple -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name classtemplate.cpp %s > %tmapping
2e3b04a9fSAlex Lorenz // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-CONSTRUCTOR
3e3b04a9fSAlex Lorenz // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-GETTER
4e3b04a9fSAlex Lorenz // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-SETTER
5a14a1f92SVedant Kumar // RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-INIT-LIST
634ac9b5eSAlex Lorenz 
734ac9b5eSAlex Lorenz template<class TT>
834ac9b5eSAlex Lorenz class Test {
934ac9b5eSAlex Lorenz public:
1034ac9b5eSAlex Lorenz   enum BaseType {
1134ac9b5eSAlex Lorenz     A, C, G, T, Invalid
1234ac9b5eSAlex Lorenz   };
1334ac9b5eSAlex Lorenz   const static int BaseCount = 4;
1434ac9b5eSAlex Lorenz   double bases[BaseCount];
1534ac9b5eSAlex Lorenz 
1694d384e4SJustin Bogner                                         // CHECK-CONSTRUCTOR: _ZN4TestIjEC
Test()174da909b2SJustin Bogner   Test() { }                            // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:10 -> [[@LINE]]:13 = #0
1894d384e4SJustin Bogner 
1994d384e4SJustin Bogner   // FIXME: It would be nice to emit no-coverage for get, but trying to do this
2094d384e4SJustin Bogner   // runs afoul of cases like Test3::unmangleable below.
2194d384e4SJustin Bogner                                         // FIXME-GETTER: _ZNK4TestIjE3get
get(TT position) const224da909b2SJustin Bogner   double get(TT position) const {       // FIXME-GETTER: File 0, [[@LINE]]:33 -> [[@LINE+2]]:4 = 0
2334ac9b5eSAlex Lorenz     return bases[position];
2434ac9b5eSAlex Lorenz   }
2594d384e4SJustin Bogner                                         // CHECK-SETTER: _ZN4TestIjE3set
set(TT position,double value)264da909b2SJustin Bogner   void set(TT position, double value) { // CHECK-SETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = #0
2734ac9b5eSAlex Lorenz     bases[position] = value;
2834ac9b5eSAlex Lorenz   }
2934ac9b5eSAlex Lorenz };
3034ac9b5eSAlex Lorenz 
3194d384e4SJustin Bogner class Test2 {
3294d384e4SJustin Bogner                                         // CHECK-CONSTRUCTOR: _ZN5Test2C
Test2()334da909b2SJustin Bogner   Test2() { }                           // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:11 -> [[@LINE]]:14 = 0
3494d384e4SJustin Bogner                                         // CHECK-GETTER: _ZNK5Test23get
get(unsigned position) const354da909b2SJustin Bogner   double get(unsigned position) const { // CHECK-GETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = 0
3694d384e4SJustin Bogner     return 0.0;
3794d384e4SJustin Bogner   }
3894d384e4SJustin Bogner };
3994d384e4SJustin Bogner 
4094d384e4SJustin Bogner // Test3::unmangleable can't be mangled, since there isn't a complete type for
4194d384e4SJustin Bogner // the __is_final type trait expression. This would cause errors if we try to
4294d384e4SJustin Bogner // emit a no-coverage mapping for the method.
4394d384e4SJustin Bogner template <class T, bool = __is_final(T)> class UninstantiatedClassWithTraits {};
4494d384e4SJustin Bogner template <class T> class Test3 {
unmangleable(UninstantiatedClassWithTraits<T> x)4594d384e4SJustin Bogner   void unmangleable(UninstantiatedClassWithTraits<T> x) {}
4694d384e4SJustin Bogner };
4794d384e4SJustin Bogner 
48a14a1f92SVedant Kumar void abort() __attribute__((noreturn));
49a14a1f92SVedant Kumar 
50a14a1f92SVedant Kumar namespace std {
51a14a1f92SVedant Kumar typedef decltype(sizeof(int)) size_t;
52a14a1f92SVedant Kumar 
53a14a1f92SVedant Kumar template <typename E> struct initializer_list {
54a14a1f92SVedant Kumar   const E *p;
55a14a1f92SVedant Kumar   size_t n;
initializer_liststd::initializer_list56a14a1f92SVedant Kumar   initializer_list(const E *p, size_t n) : p(p), n(n) {}
57a14a1f92SVedant Kumar };
58a14a1f92SVedant Kumar 
59a14a1f92SVedant Kumar template <typename F, typename S> struct pair {
60a14a1f92SVedant Kumar   F f;
61a14a1f92SVedant Kumar   S s;
pairstd::pair62a14a1f92SVedant Kumar   pair(const F &f, const S &s) : f(f), s(s) {}
63a14a1f92SVedant Kumar };
64a14a1f92SVedant Kumar 
65a14a1f92SVedant Kumar struct string {
66a14a1f92SVedant Kumar   const char *str;
stringstd::string67a14a1f92SVedant Kumar   string() { abort(); }
stringstd::string68a14a1f92SVedant Kumar   string(const char *S) : str(S) {}
~stringstd::string69a14a1f92SVedant Kumar   ~string() { abort(); }
70a14a1f92SVedant Kumar };
71a14a1f92SVedant Kumar 
72a14a1f92SVedant Kumar template<typename K, typename V>
73a14a1f92SVedant Kumar struct map {
74a14a1f92SVedant Kumar   using T = pair<K, V>;
mapstd::map75a14a1f92SVedant Kumar   map(initializer_list<T> i, const string &s = string()) {}
~mapstd::map76a14a1f92SVedant Kumar   ~map() { abort(); }
77a14a1f92SVedant Kumar };
78a14a1f92SVedant Kumar 
79a14a1f92SVedant Kumar }; // namespace std
80a14a1f92SVedant Kumar 
81a14a1f92SVedant Kumar // CHECK-INIT-LIST-LABEL: _Z5Test4v:
Test4()82a14a1f92SVedant Kumar std::map<int, int> Test4() { // CHECK-INIT-LIST: File 0, [[@LINE]]:28 -> [[@LINE+3]]:2 = #0
83*9783e209SZequan Wu   abort();                           // CHECK-INIT-LIST-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
84a14a1f92SVedant Kumar   return std::map<int, int>{{0, 0}}; // CHECK-INIT-LIST-NEXT: [[@LINE]]:3 -> [[@LINE]]:36 = 0
85a14a1f92SVedant Kumar }
86a14a1f92SVedant Kumar 
main()8734ac9b5eSAlex Lorenz int main() {
8834ac9b5eSAlex Lorenz   Test<unsigned> t;
8934ac9b5eSAlex Lorenz   t.set(Test<unsigned>::A, 5.5);
9034ac9b5eSAlex Lorenz   t.set(Test<unsigned>::T, 5.6);
9134ac9b5eSAlex Lorenz   t.set(Test<unsigned>::G, 5.7);
9234ac9b5eSAlex Lorenz   t.set(Test<unsigned>::C, 5.8);
93a14a1f92SVedant Kumar   Test4();
9434ac9b5eSAlex Lorenz   return 0;
9534ac9b5eSAlex Lorenz }
96