1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
2*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux -fms-extensions | FileCheck %s
3*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-64
4*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DWRONG_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-WRONG-GUID
5*67e74705SXin Li
6*67e74705SXin Li #ifdef DEFINE_GUID
7*67e74705SXin Li struct _GUID {
8*67e74705SXin Li #ifdef WRONG_GUID
9*67e74705SXin Li unsigned int SomethingWentWrong;
10*67e74705SXin Li #else
11*67e74705SXin Li unsigned long Data1;
12*67e74705SXin Li unsigned short Data2;
13*67e74705SXin Li unsigned short Data3;
14*67e74705SXin Li unsigned char Data4[8];
15*67e74705SXin Li #endif
16*67e74705SXin Li };
17*67e74705SXin Li #endif
18*67e74705SXin Li typedef struct _GUID GUID;
19*67e74705SXin Li
20*67e74705SXin Li struct __declspec(uuid("12345678-1234-1234-1234-1234567890aB")) S1 { } s1;
21*67e74705SXin Li struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S2 { };
22*67e74705SXin Li struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
23*67e74705SXin Li struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
24*67e74705SXin Li
25*67e74705SXin Li #ifdef DEFINE_GUID
26*67e74705SXin Li // Make sure we can properly generate code when the UUID has curly braces on it.
27*67e74705SXin Li GUID thing = __uuidof(Curly);
28*67e74705SXin Li // CHECK-DEFINE-GUID: @thing = global %struct._GUID zeroinitializer, align 4
29*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: @thing = global %struct._GUID zeroinitializer, align 4
30*67e74705SXin Li
31*67e74705SXin Li // This gets initialized in a static initializer.
32*67e74705SXin Li // CHECK-DEFINE-GUID: @g = global %struct._GUID zeroinitializer, align 4
33*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: @g = global %struct._GUID zeroinitializer, align 4
34*67e74705SXin Li GUID g = __uuidof(S1);
35*67e74705SXin Li #endif
36*67e74705SXin Li
37*67e74705SXin Li // First global use of __uuidof(S1) forces the creation of the global.
38*67e74705SXin Li // CHECK: @_GUID_12345678_1234_1234_1234_1234567890ab = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 305419896, i16 4660, i16 4660, [8 x i8] c"\124\124Vx\90\AB" }, comdat
39*67e74705SXin Li // CHECK: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
40*67e74705SXin Li // CHECK-64: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 8
41*67e74705SXin Li const GUID& gr = __uuidof(S1);
42*67e74705SXin Li
43*67e74705SXin Li // CHECK: @gp = global %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
44*67e74705SXin Li const GUID* gp = &__uuidof(S1);
45*67e74705SXin Li
46*67e74705SXin Li // CHECK: @cp = global %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to %struct._GUID*), align 4
47*67e74705SXin Li const GUID* cp = &__uuidof(Curly);
48*67e74705SXin Li
49*67e74705SXin Li // Special case: _uuidof(0)
50*67e74705SXin Li // CHECK: @zeroiid = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_00000000_0000_0000_0000_000000000000 to %struct._GUID*), align 4
51*67e74705SXin Li const GUID& zeroiid = __uuidof(0);
52*67e74705SXin Li
53*67e74705SXin Li // __uuidof(S2) hasn't been used globally yet, so it's emitted when it's used
54*67e74705SXin Li // in a function and is emitted at the end of the globals section.
55*67e74705SXin Li // CHECK: @_GUID_87654321_4321_4321_4321_ba0987654321 = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 -2023406815, i16 17185, i16 17185, [8 x i8] c"C!\BA\09\87eC!" }, comdat
56*67e74705SXin Li
57*67e74705SXin Li // The static initializer for thing.
58*67e74705SXin Li // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @thing to i8*), i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to i8*), i32 16, i32 4, i1 false)
59*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @thing to i8*), i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to i8*), i32 4, i32 4, i1 false)
60*67e74705SXin Li
61*67e74705SXin Li // The static initializer for g.
62*67e74705SXin Li // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @g to i8*), i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i32 4, i1 false)
63*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @g to i8*), i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i32 4, i1 false)
64*67e74705SXin Li
65*67e74705SXin Li #ifdef DEFINE_GUID
fun()66*67e74705SXin Li void fun() {
67*67e74705SXin Li // CHECK-DEFINE-GUID: %s1_1 = alloca %struct._GUID, align 4
68*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: %s1_1 = alloca %struct._GUID, align 4
69*67e74705SXin Li // CHECK-DEFINE-GUID: %s1_2 = alloca %struct._GUID, align 4
70*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: %s1_2 = alloca %struct._GUID, align 4
71*67e74705SXin Li // CHECK-DEFINE-GUID: %s1_3 = alloca %struct._GUID, align 4
72*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: %s1_3 = alloca %struct._GUID, align 4
73*67e74705SXin Li
74*67e74705SXin Li // CHECK-DEFINE-GUID: [[U1:%.+]] = bitcast %struct._GUID* %s1_1 to i8*
75*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: [[U1:%.+]] = bitcast %struct._GUID* %s1_1 to i8*
76*67e74705SXin Li // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U1]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i32 4, i1 false)
77*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U1]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i32 4, i1 false)
78*67e74705SXin Li GUID s1_1 = __uuidof(S1);
79*67e74705SXin Li
80*67e74705SXin Li // CHECK-DEFINE-GUID: [[U2:%.+]] = bitcast %struct._GUID* %s1_2 to i8*
81*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: [[U2:%.+]] = bitcast %struct._GUID* %s1_2 to i8*
82*67e74705SXin Li // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U2]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i32 4, i1 false)
83*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U2]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i32 4, i1 false)
84*67e74705SXin Li GUID s1_2 = __uuidof(S1);
85*67e74705SXin Li
86*67e74705SXin Li // CHECK-DEFINE-GUID: [[U3:%.+]] = bitcast %struct._GUID* %s1_3 to i8*
87*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: [[U3:%.+]] = bitcast %struct._GUID* %s1_3 to i8*
88*67e74705SXin Li // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U3]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i32 4, i1 false)
89*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[U3]], i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i32 4, i1 false)
90*67e74705SXin Li GUID s1_3 = __uuidof(s1);
91*67e74705SXin Li }
92*67e74705SXin Li #endif
93*67e74705SXin Li
gun()94*67e74705SXin Li void gun() {
95*67e74705SXin Li #ifdef DEFINE_GUID
96*67e74705SXin Li // CHECK-DEFINE-GUID: %s2_1 = alloca %struct._GUID, align 4
97*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: %s2_1 = alloca %struct._GUID, align 4
98*67e74705SXin Li // CHECK-DEFINE-GUID: %s2_2 = alloca %struct._GUID, align 4
99*67e74705SXin Li // CHECK-DEFINE-WRONG-GUID: %s2_2 = alloca %struct._GUID, align 4
100*67e74705SXin Li GUID s2_1 = __uuidof(S2);
101*67e74705SXin Li GUID s2_2 = __uuidof(S2);
102*67e74705SXin Li #endif
103*67e74705SXin Li // CHECK: %r = alloca %struct._GUID*, align 4
104*67e74705SXin Li // CHECK: %p = alloca %struct._GUID*, align 4
105*67e74705SXin Li // CHECK: %zeroiid = alloca %struct._GUID*, align 4
106*67e74705SXin Li
107*67e74705SXin Li // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_87654321_4321_4321_4321_ba0987654321 to %struct._GUID*), %struct._GUID** %r, align 4
108*67e74705SXin Li const GUID& r = __uuidof(S2);
109*67e74705SXin Li // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_87654321_4321_4321_4321_ba0987654321 to %struct._GUID*), %struct._GUID** %p, align 4
110*67e74705SXin Li const GUID* p = &__uuidof(S2);
111*67e74705SXin Li
112*67e74705SXin Li // Special case _uuidof(0), local scope version.
113*67e74705SXin Li // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_00000000_0000_0000_0000_000000000000 to %struct._GUID*), %struct._GUID** %zeroiid, align 4
114*67e74705SXin Li const GUID& zeroiid = __uuidof(0);
115*67e74705SXin Li }
116