Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
      2 
      3 // Pointers to free functions
      4 void            free_func_default();
      5 void __cdecl    free_func_cdecl();
      6 void __stdcall  free_func_stdcall(); // expected-note {{previous declaration is here}}
      7 void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}}
      8 
      9 void __cdecl    free_func_default(); // expected-note 2 {{previous declaration is here}}
     10 void __stdcall  free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
     11 void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}}
     12 
     13 void            free_func_cdecl(); // expected-note 2 {{previous declaration is here}}
     14 void __stdcall  free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
     15 void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}}
     16 
     17 void __cdecl    free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}}
     18 void            free_func_stdcall(); // expected-note {{previous declaration is here}}
     19 void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}}
     20 
     21 void __cdecl    free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}}
     22 void __stdcall  free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}}
     23 void            free_func_fastcall();
     24 
     25 // Overloaded functions may have different calling conventions
     26 void __fastcall free_func_default(int);
     27 void __cdecl    free_func_default(int *);
     28 
     29 void __thiscall free_func_cdecl(char *);
     30 void __cdecl    free_func_cdecl(double);
     31 
     32 typedef void void_fun_t();
     33 typedef void __cdecl cdecl_fun_t();
     34 
     35 // Pointers to member functions
     36 struct S {
     37   void            member_default1(); // expected-note {{previous declaration is here}}
     38   void            member_default2();
     39   void __cdecl    member_cdecl1();
     40   void __cdecl    member_cdecl2(); // expected-note {{previous declaration is here}}
     41   void __thiscall member_thiscall1();
     42   void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}}
     43 
     44   // Unless attributed, typedefs carry no calling convention and use the default
     45   // based on context.
     46   void_fun_t  member_typedef_default; // expected-note {{previous declaration is here}}
     47   cdecl_fun_t member_typedef_cdecl; // expected-note {{previous declaration is here}}
     48   __stdcall void_fun_t member_typedef_stdcall;
     49 
     50   // Static member functions can't be __thiscall
     51   static void            static_member_default1();
     52   static void            static_member_default2(); // expected-note {{previous declaration is here}}
     53   static void __cdecl    static_member_cdecl1();
     54   static void __cdecl    static_member_cdecl2(); // expected-note {{previous declaration is here}}
     55   static void __stdcall  static_member_stdcall1();
     56   static void __stdcall  static_member_stdcall2();
     57 
     58   // Variadic functions can't be other than default or __cdecl
     59   void            member_variadic_default(int x, ...);
     60   void __cdecl    member_variadic_cdecl(int x, ...);
     61 
     62   static void            static_member_variadic_default(int x, ...);
     63   static void __cdecl    static_member_variadic_cdecl(int x, ...);
     64 };
     65 
     66 void __cdecl    S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
     67 void __thiscall S::member_default2() {}
     68 
     69 void __cdecl S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
     70 void __thiscall S::member_typedef_cdecl() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
     71 void __stdcall S::member_typedef_stdcall() {}
     72 
     73 void            S::member_cdecl1() {}
     74 void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
     75 
     76 void            S::member_thiscall1() {}
     77 void __cdecl    S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}}
     78 
     79 void __cdecl    S::static_member_default1() {}
     80 void __stdcall  S::static_member_default2() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
     81 
     82 void            S::static_member_cdecl1() {}
     83 void __stdcall  S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
     84 
     85 void __cdecl    S::member_variadic_default(int x, ...) {
     86   (void)x;
     87 }
     88 void            S::member_variadic_cdecl(int x, ...) {
     89   (void)x;
     90 }
     91 
     92 void __cdecl    S::static_member_variadic_default(int x, ...) {
     93   (void)x;
     94 }
     95 void            S::static_member_variadic_cdecl(int x, ...) {
     96   (void)x;
     97 }
     98 
     99 // Declare a template using a calling convention.
    100 template <class CharT> inline int __cdecl mystrlen(const CharT *str) {
    101   int i;
    102   for (i = 0; str[i]; i++) { }
    103   return i;
    104 }
    105 extern int sse_strlen(const char *str);
    106 template <> inline int __cdecl mystrlen(const char *str) {
    107   return sse_strlen(str);
    108 }
    109 void use_tmpl(const char *str, const int *ints) {
    110   mystrlen(str);
    111   mystrlen(ints);
    112 }
    113