Home | History | Annotate | Download | only in Sema
      1 // RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -fms-extensions -verify -std=c99 %s
      2 // RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -fms-extensions -verify -std=c11 %s
      3 // RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -fms-extensions -verify -std=c11 %s
      4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 %s
      5 
      6 // Invalid usage.
      7 __declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
      8 typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
      9 typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
     10 typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
     11 enum __declspec(dllexport) Enum { EnumVal }; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
     12 struct __declspec(dllexport) Record {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
     13 
     14 
     15 
     16 //===----------------------------------------------------------------------===//
     17 // Globals
     18 //===----------------------------------------------------------------------===//
     19 
     20 // Export declaration.
     21 __declspec(dllexport) extern int ExternGlobalDecl;
     22 
     23 // dllexport implies a definition.
     24 __declspec(dllexport) int GlobalDef;
     25 
     26 // Export definition.
     27 __declspec(dllexport) int GlobalInit1 = 1;
     28 int __declspec(dllexport) GlobalInit2 = 1;
     29 
     30 // Declare, then export definition.
     31 __declspec(dllexport) extern int GlobalDeclInit;
     32 int GlobalDeclInit = 1;
     33 
     34 // Redeclarations
     35 __declspec(dllexport) extern int GlobalRedecl1;
     36 __declspec(dllexport)        int GlobalRedecl1;
     37 
     38 __declspec(dllexport) extern int GlobalRedecl2;
     39                              int GlobalRedecl2;
     40 
     41                       extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
     42 int useGlobalRedecl3() { return GlobalRedecl3; }
     43 __declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
     44 
     45                       extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
     46 __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}}
     47 
     48 
     49 // External linkage is required.
     50 __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
     51 
     52 // Thread local variables are invalid.
     53 __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
     54 
     55 // Export in local scope.
     56 void functionScope() {
     57   __declspec(dllexport)        int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
     58   __declspec(dllexport)        int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
     59   __declspec(dllexport) extern int ExternLocalVarDecl;
     60   __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
     61 }
     62 
     63 
     64 
     65 //===----------------------------------------------------------------------===//
     66 // Functions
     67 //===----------------------------------------------------------------------===//
     68 
     69 // Export function declaration. Check different placements.
     70 __attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
     71 __declspec(dllexport)      void decl1B();
     72 
     73 void __attribute__((dllexport)) decl2A();
     74 void __declspec(dllexport)      decl2B();
     75 
     76 // Export function definition.
     77 __declspec(dllexport) void def() {}
     78 
     79 // Export inline function.
     80 __declspec(dllexport) inline void inlineFunc1() {}
     81 extern void inlineFunc1();
     82 
     83 inline void __attribute__((dllexport)) inlineFunc2() {}
     84 extern void inlineFunc2();
     85 
     86 // Redeclarations
     87 __declspec(dllexport) void redecl1();
     88 __declspec(dllexport) void redecl1();
     89 
     90 __declspec(dllexport) void redecl2();
     91                       void redecl2();
     92 
     93 __declspec(dllexport) void redecl3();
     94                       void redecl3() {}
     95 
     96                       void redecl4(); // expected-note{{previous declaration is here}}
     97 void useRedecl4() { redecl4(); }
     98 __declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}
     99 
    100                       void redecl5(); // expected-note{{previous declaration is here}}
    101 void useRedecl5() { redecl5(); }
    102 __declspec(dllexport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllexport' attribute}}
    103 
    104 // Allow with a warning if the decl hasn't been used yet.
    105                       void redecl6(); // expected-note{{previous declaration is here}}
    106 __declspec(dllexport) void redecl6(); // expected-warning{{redeclaration of 'redecl6' should not add 'dllexport' attribute}}
    107 
    108 
    109 // External linkage is required.
    110 __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
    111 
    112 // Static locals don't count as having external linkage.
    113 void staticLocalFunc() {
    114   __declspec(dllexport) static int staticLocal; // expected-error{{'staticLocal' must have external linkage when declared 'dllexport'}}
    115 }
    116 
    117 
    118 
    119 //===----------------------------------------------------------------------===//
    120 // Precedence
    121 //===----------------------------------------------------------------------===//
    122 
    123 // dllexport takes precedence over dllimport if both are specified.
    124 __attribute__((dllimport, dllexport))       extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
    125 __declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
    126 
    127 __attribute__((dllexport, dllimport))       extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
    128 __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
    129 
    130 __attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
    131 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
    132 
    133 __attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
    134 __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
    135 
    136 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
    137 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
    138 
    139 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
    140 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
    141 
    142 __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
    143 __declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
    144 
    145 __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
    146 __declspec(dllexport)        int PrecedenceGlobalRedecl2;
    147 
    148 void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
    149 void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
    150 
    151 void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
    152 void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
    153 
    154 void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
    155 void __declspec(dllexport) precedenceRedecl1() {}
    156 
    157 void __declspec(dllexport) precedenceRedecl2();
    158 void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
    159