Skip to content

Commit 755a36f

Browse files
committed
IRGen: Add more tests for dll attributes
llvm-svn: 209596
1 parent 0a43761 commit 755a36f

File tree

8 files changed

+2683
-65
lines changed

8 files changed

+2683
-65
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5056,7 +5056,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
50565056
// dllimport globals without explicit storage class are treated as extern. We
50575057
// have to change the storage class this early to get the right DeclContext.
50585058
if (SC == SC_None && !DC->isRecord() &&
5059-
hasParsedAttr(S, D, AttributeList::AT_DLLImport))
5059+
hasParsedAttr(S, D, AttributeList::AT_DLLImport) &&
5060+
!hasParsedAttr(S, D, AttributeList::AT_DLLExport))
50605061
SC = SC_Extern;
50615062

50625063
DeclContext *OriginalDC = DC;

clang/test/CodeGen/dllexport.c

Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,115 @@
1-
// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -emit-llvm < %s | FileCheck %s
1+
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
3+
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
4+
// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
25

3-
#define DLLEXPORT __declspec(dllexport)
46

5-
inline void DLLEXPORT f() {}
6-
extern void DLLEXPORT f();
77

8-
// CHECK: define weak_odr dllexport void @f()
8+
//===----------------------------------------------------------------------===//
9+
// Globals
10+
//===----------------------------------------------------------------------===//
11+
12+
// Declarations are not exported.
13+
// CHECK-NOT: @ExternGlobalDecl
14+
__declspec(dllexport) extern int ExternGlobalDecl;
15+
16+
// dllexport implies a definition.
17+
// CHECK-DAG: @GlobalDef = common dllexport global i32 0, align 4
18+
__declspec(dllexport) int GlobalDef;
19+
20+
// Export definition.
21+
// CHECK-DAG: @GlobalInit = dllexport global i32 1, align 4
22+
__declspec(dllexport) int GlobalInit = 1;
23+
24+
// Declare, then export definition.
25+
// CHECK-DAG: @GlobalDeclInit = dllexport global i32 1, align 4
26+
__declspec(dllexport) extern int GlobalDeclInit;
27+
int GlobalDeclInit = 1;
28+
29+
// Redeclarations
30+
// CHECK-DAG: @GlobalRedecl1 = common dllexport global i32 0, align 4
31+
__declspec(dllexport) extern int GlobalRedecl1;
32+
__declspec(dllexport) int GlobalRedecl1;
33+
34+
// CHECK-DAG: @GlobalRedecl2 = common dllexport global i32 0, align 4
35+
__declspec(dllexport) extern int GlobalRedecl2;
36+
int GlobalRedecl2;
37+
38+
39+
40+
//===----------------------------------------------------------------------===//
41+
// Functions
42+
//===----------------------------------------------------------------------===//
43+
44+
// Declarations are not exported.
45+
46+
// Export function definition.
47+
// CHECK-DAG: define dllexport void @def()
48+
__declspec(dllexport) void def(void) {}
49+
50+
// Export inline function.
51+
// CHECK-DAG: define weak_odr dllexport void @inlineFunc()
52+
// CHECK-DAG: define weak_odr dllexport void @externInlineFunc()
53+
__declspec(dllexport) inline void inlineFunc(void) {}
54+
__declspec(dllexport) inline void externInlineFunc(void) {}
55+
extern void externInlineFunc(void);
56+
57+
// Redeclarations
58+
// CHECK-DAG: define dllexport void @redecl1()
59+
__declspec(dllexport) void redecl1(void);
60+
__declspec(dllexport) void redecl1(void) {}
61+
62+
// CHECK-DAG: define dllexport void @redecl2()
63+
__declspec(dllexport) void redecl2(void);
64+
void redecl2(void) {}
65+
66+
67+
68+
//===----------------------------------------------------------------------===//
69+
// Precedence
70+
//===----------------------------------------------------------------------===//
71+
72+
// dllexport takes precedence over the dllimport if both are specified.
73+
// CHECK-DAG: @PrecedenceGlobal1A = common dllexport global i32 0, align 4
74+
// CHECK-DAG: @PrecedenceGlobal1B = common dllexport global i32 0, align 4
75+
__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A;
76+
__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B;
77+
78+
// CHECK-DAG: @PrecedenceGlobal2A = common dllexport global i32 0, align 4
79+
// CHECK-DAG: @PrecedenceGlobal2B = common dllexport global i32 0, align 4
80+
__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A;
81+
__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B;
82+
83+
// CHECK-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4
84+
__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
85+
__declspec(dllimport) int PrecedenceGlobalRedecl1 = 0;
86+
87+
// CHECK-DAG: @PrecedenceGlobalRedecl2 = common dllexport global i32 0, align 4
88+
__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
89+
__declspec(dllexport) int PrecedenceGlobalRedecl2;
90+
91+
// CHECK-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 1, align 4
92+
__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
93+
__declspec(dllimport) int PrecedenceGlobalMixed1 = 1;
94+
95+
// CHECK-DAG: @PrecedenceGlobalMixed2 = common dllexport global i32 0, align 4
96+
__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
97+
__declspec(dllexport) int PrecedenceGlobalMixed2;
98+
99+
// CHECK-DAG: define dllexport void @precedence1A()
100+
// CHECK-DAG: define dllexport void @precedence1B()
101+
void __attribute__((dllimport, dllexport)) precedence1A(void) {}
102+
void __declspec(dllimport) __declspec(dllexport) precedence1B(void) {}
103+
104+
// CHECK-DAG: define dllexport void @precedence2A()
105+
// CHECK-DAG: define dllexport void @precedence2B()
106+
void __attribute__((dllexport, dllimport)) precedence2A(void) {}
107+
void __declspec(dllexport) __declspec(dllimport) precedence2B(void) {}
108+
109+
// CHECK-DAG: define dllexport void @precedenceRedecl1()
110+
void __declspec(dllimport) precedenceRedecl1(void);
111+
void __declspec(dllexport) precedenceRedecl1(void) {}
112+
113+
// CHECK-DAG: define dllexport void @precedenceRedecl2()
114+
void __declspec(dllexport) precedenceRedecl2(void);
115+
void __declspec(dllimport) precedenceRedecl2(void) {}

clang/test/CodeGen/dllimport-dllexport.c

Lines changed: 0 additions & 22 deletions
This file was deleted.

clang/test/CodeGen/dllimport.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
3+
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
4+
// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
5+
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
6+
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
7+
8+
#define JOIN2(x, y) x##y
9+
#define JOIN(x, y) JOIN2(x, y)
10+
#define USEVAR(var) int JOIN(use, __LINE__)() { return var; }
11+
#define USE(func) void JOIN(use, __LINE__)() { func(); }
12+
13+
14+
15+
//===----------------------------------------------------------------------===//
16+
// Globals
17+
//===----------------------------------------------------------------------===//
18+
19+
// Import declaration.
20+
// CHECK: @ExternGlobalDecl = external dllimport global i32
21+
__declspec(dllimport) extern int ExternGlobalDecl;
22+
USEVAR(ExternGlobalDecl)
23+
24+
// dllimport implies a declaration.
25+
// CHECK: @GlobalDecl = external dllimport global i32
26+
__declspec(dllimport) int GlobalDecl;
27+
USEVAR(GlobalDecl)
28+
29+
// Redeclarations
30+
// CHECK: @GlobalRedecl1 = external dllimport global i32
31+
__declspec(dllimport) extern int GlobalRedecl1;
32+
__declspec(dllimport) extern int GlobalRedecl1;
33+
USEVAR(GlobalRedecl1)
34+
35+
// CHECK: @GlobalRedecl2 = external dllimport global i32
36+
__declspec(dllimport) int GlobalRedecl2;
37+
__declspec(dllimport) int GlobalRedecl2;
38+
USEVAR(GlobalRedecl2)
39+
40+
// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
41+
// and drop the dllimport with a warning.
42+
// CHECK: @GlobalRedecl3 = external global i32
43+
__declspec(dllimport) extern int GlobalRedecl3;
44+
extern int GlobalRedecl3; // dllimport ignored
45+
USEVAR(GlobalRedecl3)
46+
47+
48+
49+
//===----------------------------------------------------------------------===//
50+
// Functions
51+
//===----------------------------------------------------------------------===//
52+
53+
// Import function declaration.
54+
// CHECK-DAG: declare dllimport void @decl()
55+
__declspec(dllimport) void decl(void);
56+
USE(decl)
57+
58+
// Import inline function.
59+
// CHECK-DAG: declare dllimport void @inlineFunc()
60+
// O1-DAG: define available_externally dllimport void @inlineFunc()
61+
__declspec(dllimport) inline void inlineFunc(void) {}
62+
USE(inlineFunc)
63+
64+
// inline attributes
65+
// CHECK-DAG: declare dllimport void @noinline()
66+
// O1-DAG: define available_externally dllimport void @noinline()
67+
// CHECK-NOT: @alwaysInline()
68+
// O1-NOT: @alwaysInline()
69+
__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
70+
__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
71+
USE(noinline)
72+
USE(alwaysInline)
73+
74+
// Redeclarations
75+
// CHECK-DAG: declare dllimport void @redecl1()
76+
__declspec(dllimport) void redecl1(void);
77+
__declspec(dllimport) void redecl1(void);
78+
USE(redecl1)
79+
80+
// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
81+
// and drop the dllimport with a warning.
82+
// CHECK-DAG: declare void @redecl2()
83+
__declspec(dllimport) void redecl2(void);
84+
void redecl2(void);
85+
USE(redecl2)
86+
87+
// CHECK-DAG: define void @redecl3()
88+
__declspec(dllimport) void redecl3(void);
89+
void redecl3(void) {} // dllimport ignored
90+
USE(redecl3)

0 commit comments

Comments
 (0)