Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
      2 
      3 template<typename Signature>
      4 class C;
      5 
      6 template<typename Ret>
      7 class C<Ret(void)> {};
      8 typedef C<void(void)> C0;
      9 
     10 template<typename Ret, typename Arg1>
     11 class C<Ret(Arg1)> {};
     12 
     13 template<typename Ret, typename Arg1, typename Arg2>
     14 class C<Ret(Arg1, Arg2)> {};
     15 
     16 C0 callback_void;
     17 // CHECK: "\01?callback_void@@3V?$C@$$A6AXXZ@@A"
     18 
     19 volatile C0 callback_void_volatile;
     20 // CHECK: "\01?callback_void_volatile@@3V?$C@$$A6AXXZ@@C"
     21 
     22 class Type {};
     23 
     24 C<int(void)> callback_int;
     25 // CHECK: "\01?callback_int@@3V?$C@$$A6AHXZ@@A"
     26 C<Type(void)> callback_Type;
     27 // CHECK: "\01?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A"
     28 
     29 C<void(int)> callback_void_int;
     30 // CHECK: "\01?callback_void_int@@3V?$C@$$A6AXH@Z@@A"
     31 C<int(int)> callback_int_int;
     32 // CHECK: "\01?callback_int_int@@3V?$C@$$A6AHH@Z@@A"
     33 C<void(Type)> callback_void_Type;
     34 // CHECK: "\01?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A"
     35 
     36 void foo(C0 c) {}
     37 // CHECK: "\01?foo@@YAXV?$C@$$A6AXXZ@@@Z"
     38 
     39 // Here be dragons!
     40 // Let's face the magic of template partial specialization...
     41 
     42 void function(C<void(void)>) {}
     43 // CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z"
     44 
     45 template<typename Ret> class C<Ret(*)(void)> {};
     46 void function_pointer(C<void(*)(void)>) {}
     47 // CHECK: "\01?function_pointer@@YAXV?$C@P6AXXZ@@@Z"
     48 
     49 // Block equivalent to the previous definitions.
     50 template<typename Ret> class C<Ret(^)(void)> {};
     51 void block(C<void(^)(void)>) {}
     52 // CHECK: "\01?block@@YAXV?$C@P_EAXXZ@@@Z"
     53 // FYI blocks are not present in MSVS, so we're free to choose the spec.
     54 
     55 template<typename T> class C<void (T::*)(void)> {};
     56 class Z {
     57  public:
     58   void method() {}
     59 };
     60 void member_pointer(C<void (Z::*)(void)>) {}
     61 // CHECK: "\01?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z"
     62 
     63 template<typename T> void bar(T) {}
     64 
     65 void call_bar() {
     66   bar<int (*)(int)>(0);
     67 // CHECK: "\01??$bar@P6AHH@Z@@YAXP6AHH@Z@Z"
     68 
     69   bar<int (^)(int)>(0);
     70 // CHECK: "\01??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z"
     71 // FYI blocks are not present in MSVS, so we're free to choose the spec.
     72 }
     73 
     74 template <void (*Fn)()> void WrapFnPtr() { Fn(); }
     75 template <void (&Fn)()> void WrapFnRef() { Fn(); }
     76 struct Thing {
     77   static void VoidStaticMethod();
     78 };
     79 void VoidFn();
     80 void CallWrapper() {
     81   WrapFnPtr<VoidFn>();
     82   WrapFnRef<VoidFn>();
     83   WrapFnPtr<Thing::VoidStaticMethod>();
     84   WrapFnRef<Thing::VoidStaticMethod>();
     85 }
     86 // CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidFn@@YAXXZ@@YAXXZ"
     87 // CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidFn@@YAXXZ@@YAXXZ"
     88 // CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
     89 // CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
     90