1 | // RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -verify |
2 | // RUN: not %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s |
3 | |
4 | struct X; |
5 | namespace name_at_tu_scope { |
6 | struct Y { |
7 | friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}} |
8 | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"::" |
9 | }; |
10 | } |
11 | |
12 | namespace enclosing_friend_decl { |
13 | struct B; |
14 | namespace ns { |
15 | struct A { |
16 | friend struct B; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}} |
17 | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"enclosing_friend_decl::" |
18 | protected: |
19 | A(); |
20 | }; |
21 | } |
22 | struct B { |
23 | static void f() { ns::A x; } |
24 | }; |
25 | } |
26 | |
27 | namespace enclosing_friend_qualified { |
28 | struct B; |
29 | namespace ns { |
30 | struct A { |
31 | friend struct enclosing_friend_qualified::B; // Adding name specifiers fixes it. |
32 | protected: |
33 | A(); |
34 | }; |
35 | } |
36 | struct B { |
37 | static void f() { ns::A x; } |
38 | }; |
39 | } |
40 | |
41 | namespace enclosing_friend_no_tag { |
42 | struct B; |
43 | namespace ns { |
44 | struct A { |
45 | friend B; // Removing the tag decl fixes it. |
46 | protected: |
47 | A(); |
48 | }; |
49 | } |
50 | struct B { |
51 | static void f() { ns::A x; } |
52 | }; |
53 | } |
54 | |
55 | namespace enclosing_friend_func { |
56 | void f(); |
57 | namespace ns { |
58 | struct A { |
59 | // Amusingly, in MSVC, this declares ns::f(), and doesn't find the outer f(). |
60 | friend void f(); |
61 | protected: |
62 | A(); // expected-note {{declared protected here}} |
63 | }; |
64 | } |
65 | void f() { ns::A x; } // expected-error {{calling a protected constructor of class 'enclosing_friend_func::ns::A'}} |
66 | } |
67 | |
68 | namespace test_nns_fixit_hint { |
69 | namespace name1 { |
70 | namespace name2 { |
71 | struct X; |
72 | struct name2; |
73 | namespace name3 { |
74 | struct Y { |
75 | friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}} |
76 | // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"name1::name2::" |
77 | }; |
78 | } |
79 | } |
80 | } |
81 | } |
82 | |
83 | // A friend declaration injects a forward declaration into the nearest enclosing |
84 | // non-member scope. |
85 | namespace friend_as_a_forward_decl { |
86 | |
87 | class A { |
88 | class Nested { |
89 | friend class B; |
90 | B *b; |
91 | }; |
92 | B *b; |
93 | }; |
94 | B *global_b; |
95 | |
96 | void f() { |
97 | class Local { |
98 | friend class Z; |
99 | Z *b; |
100 | }; |
101 | Z *b; |
102 | } |
103 | |
104 | } |
105 | |