Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
      2 
      3 template<class X, class Y, class Z>
      4 class A {};
      5 template<class X>
      6 class B {};
      7 template<class X>
      8 class C {};
      9 
     10 void foo_abbb(A<B<char>, B<char>, B<char> >) {}
     11 // CHECK: "\01?foo_abbb@@YAXV?$A@V?$B@D@@V1@V1@@@@Z"
     12 void foo_abb(A<char, B<char>, B<char> >) {}
     13 // CHECK: "\01?foo_abb@@YAXV?$A@DV?$B@D@@V1@@@@Z"
     14 void foo_abc(A<char, B<char>, C<char> >) {}
     15 // CHECK: "\01?foo_abc@@YAXV?$A@DV?$B@D@@V?$C@D@@@@@Z"
     16 void foo_bt(bool a, B<bool(bool)> b) {}
     17 // CHECK: "\01?foo_bt@@YAX_NV?$B@$$A6A_N_N@Z@@@Z"
     18 
     19 namespace N {
     20 template<class X, class Y, class Z>
     21 class A {};
     22 template<class X>
     23 class B {};
     24 template<class X>
     25 class C {};
     26 template<class X, class Y>
     27 class D {};
     28 class Z {};
     29 }
     30 
     31 void foo_abbb(N::A<N::B<char>, N::B<char>, N::B<char> >) {}
     32 // CHECK: "\01?foo_abbb@@YAXV?$A@V?$B@D@N@@V12@V12@@N@@@Z"
     33 void foo_abb(N::A<char, N::B<char>, N::B<char> >) {}
     34 // CHECK: "\01?foo_abb@@YAXV?$A@DV?$B@D@N@@V12@@N@@@Z"
     35 void foo_abc(N::A<char, N::B<char>, N::C<char> >) {}
     36 // CHECK: "\01?foo_abc@@YAXV?$A@DV?$B@D@N@@V?$C@D@2@@N@@@Z"
     37 
     38 N::A<char, N::B<char>, N::C<char> > abc_foo() {
     39 // CHECK: ?abc_foo@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@XZ
     40   return N::A<char, N::B<char>, N::C<char> >();
     41 }
     42 
     43 N::Z z_foo(N::Z arg) {
     44 // CHECK: ?z_foo@@YA?AVZ@N@@V12@@Z
     45   return arg;
     46 }
     47 
     48 N::B<char> b_foo(N::B<char> arg) {
     49 // CHECK: ?b_foo@@YA?AV?$B@D@N@@V12@@Z
     50   return arg;
     51 }
     52 
     53 N::D<char, char> d_foo(N::D<char, char> arg) {
     54 // CHECK: ?d_foo@@YA?AV?$D@DD@N@@V12@@Z
     55   return arg;
     56 }
     57 
     58 N::A<char, N::B<char>, N::C<char> > abc_foo_abc(N::A<char, N::B<char>, N::C<char> >) {
     59 // CHECK: ?abc_foo_abc@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@V12@@Z
     60   return N::A<char, N::B<char>, N::C<char> >();
     61 }
     62 
     63 namespace NA {
     64 class X {};
     65 template<class T> class Y {};
     66 }
     67 
     68 namespace NB {
     69 class X {};
     70 template<class T> class Y {};
     71 }
     72 
     73 void foo5(NA::Y<NB::Y<NA::Y<NB::Y<NA::X> > > > arg) {}
     74 // CHECK: "\01?foo5@@YAXV?$Y@V?$Y@V?$Y@V?$Y@VX@NA@@@NB@@@NA@@@NB@@@NA@@@Z"
     75 
     76 void foo11(NA::Y<NA::X>, NB::Y<NA::X>) {}
     77 // CHECK: "\01?foo11@@YAXV?$Y@VX@NA@@@NA@@V1NB@@@Z"
     78 
     79 void foo112(NA::Y<NA::X>, NB::Y<NB::X>) {}
     80 // CHECK: "\01?foo112@@YAXV?$Y@VX@NA@@@NA@@V?$Y@VX@NB@@@NB@@@Z"
     81 
     82 void foo22(NA::Y<NB::Y<NA::X> >, NB::Y<NA::Y<NA::X> >) {}
     83 // CHECK: "\01?foo22@@YAXV?$Y@V?$Y@VX@NA@@@NB@@@NA@@V?$Y@V?$Y@VX@NA@@@NA@@@NB@@@Z"
     84 
     85 namespace PR13207 {
     86 class A {};
     87 class B {};
     88 class C {};
     89 
     90 template<class X>
     91 class F {};
     92 template<class X>
     93 class I {};
     94 template<class X, class Y>
     95 class J {};
     96 template<class X, class Y, class Z>
     97 class K {};
     98 
     99 class L {
    100  public:
    101   void foo(I<A> x) {}
    102 };
    103 // CHECK: "\01?foo@L@PR13207@@QAEXV?$I@VA@PR13207@@@2@@Z"
    104 
    105 void call_l_foo(L* l) { l->foo(I<A>()); }
    106 
    107 void foo(I<A> x) {}
    108 // CHECK: "\01?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z"
    109 void foo2(I<A> x, I<A> y) { }
    110 // CHECK: "\01?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z"
    111 void bar(J<A,B> x) {}
    112 // CHECK: "\01?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z"
    113 void spam(K<A,B,C> x) {}
    114 // CHECK: "\01?spam@PR13207@@YAXV?$K@VA@PR13207@@VB@2@VC@2@@1@@Z"
    115 
    116 void baz(K<char, F<char>, I<char> >) {}
    117 // CHECK: "\01?baz@PR13207@@YAXV?$K@DV?$F@D@PR13207@@V?$I@D@2@@1@@Z"
    118 void qux(K<char, I<char>, I<char> >) {}
    119 // CHECK: "\01?qux@PR13207@@YAXV?$K@DV?$I@D@PR13207@@V12@@1@@Z"
    120 
    121 namespace NA {
    122 class X {};
    123 template<class T> class Y {};
    124 void foo(Y<X> x) {}
    125 // CHECK: "\01?foo@NA@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
    126 void foofoo(Y<Y<X> > x) {}
    127 // CHECK: "\01?foofoo@NA@PR13207@@YAXV?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@12@@Z"
    128 }
    129 
    130 namespace NB {
    131 class X {};
    132 template<class T> class Y {};
    133 void foo(Y<NA::X> x) {}
    134 // CHECK: "\01?foo@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
    135 
    136 void bar(NA::Y<X> x) {}
    137 // CHECK: "\01?bar@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@NA@2@@Z"
    138 
    139 void spam(NA::Y<NA::X> x) {}
    140 // CHECK: "\01?spam@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@NA@2@@Z"
    141 
    142 void foobar(NA::Y<Y<X> > a, Y<Y<X> >) {}
    143 // CHECK: "\01?foobar@NB@PR13207@@YAXV?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V312@@Z"
    144 
    145 void foobarspam(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >) {}
    146 // CHECK: "\01?foobarspam@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@@Z"
    147 
    148 void foobarbaz(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c) {}
    149 // CHECK: "\01?foobarbaz@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2@Z"
    150 
    151 void foobarbazqux(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c , NA::Y<Y<Y<X> > > d) {}
    152 // CHECK: "\01?foobarbazqux@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2V?$Y@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NB@PR13207@@@52@@Z"
    153 }
    154 
    155 namespace NC {
    156 class X {};
    157 template<class T> class Y {};
    158 
    159 void foo(Y<NB::X> x) {}
    160 // CHECK: "\01?foo@NC@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@@Z"
    161 
    162 void foobar(NC::Y<NB::Y<NA::Y<NA::X> > > x) {}
    163 // CHECK: "\01?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z"
    164 }
    165 }
    166 
    167 // Function template names are not considered for backreferencing, but normal
    168 // function names are.
    169 namespace fn_space {
    170 struct RetVal { int hash; };
    171 template <typename T>
    172 RetVal fun_tmpl(const T &t) { return RetVal(); }
    173 RetVal fun_normal(int t) { return RetVal(); }
    174 void fun_instantiate() {
    175   fun_normal(1);
    176   fun_tmpl(1);
    177 }
    178 // CHECK: "\01?fun_normal@fn_space@@YA?AURetVal@1@H@Z"
    179 // CHECK: "\01??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z"
    180 
    181 template <typename T, RetVal (*F)(T)>
    182 RetVal fun_tmpl_recurse(T t) {
    183   if (!t)
    184     return RetVal();
    185   return F(t - 1);
    186 }
    187 RetVal ident(int x) { return RetVal(); }
    188 void fun_instantiate2() {
    189   fun_tmpl_recurse<int, fun_tmpl_recurse<int, ident> >(10);
    190 }
    191 // CHECK: "\01??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z"
    192 // CHECK: "\01??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z"
    193 }
    194