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