1 // RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -Wno-deprecated-declarations
2 // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -fms-extensions %s -Wno-deprecated-declarations
8 __UINT8_TYPE__ Data4
[8];
12 // cl.exe's behavior with merging uuid attributes is a bit erratic:
13 // * In []-style attributes, a single [] list must not list a duplicate uuid
14 // (even if it's the same uuid), and only a single declaration of a class
15 // must have a uuid else the compiler errors out (even if two declarations of
16 // a class have the same uuid).
17 // * For __declspec(uuid(...)), it's ok if several declarations of a class have
18 // an uuid, as long as it's the same uuid each time. If uuids on declarations
19 // don't match, the compiler errors out.
20 // * If there are several __declspec(uuid(...))s on one declaration, the
21 // compiler only warns about this and uses the last uuid. It even warns if
22 // the uuids are the same.
24 // clang-cl implements the following simpler (but largely compatible) behavior
26 // * [] and __declspec uuids have the same behavior.
27 // * If there are several uuids on a class (no matter if on the same decl or
28 // on several decls), it is an error if they don't match.
29 // * Having several uuids that match is ok.
31 // Both cl and clang-cl accept this:
32 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C1
;
33 class __declspec(uuid("000000a0-0000-0000-c000-000000000049")) C1
;
34 class __declspec(uuid("{000000a0-0000-0000-C000-000000000049}")) C1
;
35 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C1
{};
37 // Both cl and clang-cl error out on this:
38 // expected-note@+1 2{{previous uuid specified here}}
39 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C2
;
40 // expected-error@+1 {{uuid does not match previous declaration}}
41 class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C2
;
42 // expected-error@+1 {{uuid does not match previous declaration}}
43 class __declspec(uuid("220000A0-0000-0000-C000-000000000049")) C2
{};
45 // expected-note@+1 {{previous uuid specified here}}
46 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C2_2
;
48 // expected-error@+1 {{uuid does not match previous declaration}}
49 class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C2_2
;
51 // clang-cl accepts this, but cl errors out:
52 [uuid("000000A0-0000-0000-C000-000000000049")] class C3
;
53 [uuid("000000A0-0000-0000-C000-000000000049")] class C3
;
54 [uuid("000000A0-0000-0000-C000-000000000049")] class C3
{};
56 // Both cl and clang-cl error out on this (but for different reasons):
57 // expected-note@+1 2{{previous uuid specified here}}
58 [uuid("000000A0-0000-0000-C000-000000000049")] class C4
;
59 // expected-error@+1 {{uuid does not match previous declaration}}
60 [uuid("110000A0-0000-0000-C000-000000000049")] class C4
;
61 // expected-error@+1 {{uuid does not match previous declaration}}
62 [uuid("220000A0-0000-0000-C000-000000000049")] class C4
{};
64 // Both cl and clang-cl error out on this:
65 // expected-error@+1 {{uuid does not match previous declaration}}
66 class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
67 // expected-note@+1 {{previous uuid specified here}}
68 __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C5
;
70 // expected-error@+1 {{uuid does not match previous declaration}}
71 [uuid("000000A0-0000-0000-C000-000000000049"),
72 // expected-note@+1 {{previous uuid specified here}}
73 uuid("110000A0-0000-0000-C000-000000000049")] class C6
;
75 // cl doesn't diagnose having one uuid each as []-style attributes and as
76 // __declspec, even if the uuids differ. clang-cl errors if they differ.
77 [uuid("000000A0-0000-0000-C000-000000000049")]
78 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C7
;
80 // expected-note@+1 {{previous uuid specified here}}
81 [uuid("000000A0-0000-0000-C000-000000000049")]
82 // expected-error@+1 {{uuid does not match previous declaration}}
83 class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C8
;
86 // cl warns on this, but clang-cl is fine with it (which is consistent with
87 // e.g. specifying __multiple_inheritance several times, which cl accepts
88 // without warning too).
89 class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
90 __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C9
;
92 // cl errors out on this, but clang-cl is fine with it (to be consistent with
93 // the previous case).
94 [uuid("000000A0-0000-0000-C000-000000000049"),
95 uuid("000000A0-0000-0000-C000-000000000049")] class C10
;
97 template <const GUID
* p
>
99 // Regression test for PR24986. The given GUID should just work as a pointer.
104 // The UUID should work for a non-type template parameter.
110 // Test class/struct redeclaration where the subsequent
111 // declaration has a uuid attribute
114 struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) X
;
116 namespace ConstantEvaluation
{
117 class __declspec(uuid("1babb1ed-feed-c01d-1ced-decafc0ffee5")) Request
;
118 constexpr GUID a
= __uuidof(Request
);
119 static_assert(a
.Data1
== 0x1babb1ed, "");
120 static_assert(__uuidof(Request
).Data1
== 0x1babb1ed, "");
121 static_assert(a
.Data2
== 0xfeed, "");
122 static_assert(__uuidof(Request
).Data2
== 0xfeed, "");
123 static_assert(a
.Data3
== 0xc01d, "");
124 static_assert(__uuidof(Request
).Data3
== 0xc01d, "");
125 static_assert(a
.Data4
[0] == 0x1c, "");
126 static_assert(__uuidof(Request
).Data4
[0] == 0x1c, "");
127 static_assert(a
.Data4
[1] == 0xed, "");
128 static_assert(__uuidof(Request
).Data4
[1] == 0xed, "");
129 static_assert(a
.Data4
[2] == 0xde, "");
130 static_assert(__uuidof(Request
).Data4
[2] == 0xde, "");
131 static_assert(a
.Data4
[7] == 0xe5, "");
132 static_assert(__uuidof(Request
).Data4
[7] == 0xe5, "");
133 constexpr int k
= __uuidof(Request
).Data4
[8]; // expected-error {{constant expression}} expected-note {{past-the-end}}