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
4struct X;
5namespace name_at_tu_scope {
6struct 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
12namespace enclosing_friend_decl {
13struct B;
14namespace ns {
15struct 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::"
18protected:
19  A();
20};
21}
22struct B {
23  static void f() { ns::A x; }
24};
25}
26
27namespace enclosing_friend_qualified {
28struct B;
29namespace ns {
30struct A {
31  friend struct enclosing_friend_qualified::B; // Adding name specifiers fixes it.
32protected:
33  A();
34};
35}
36struct B {
37  static void f() { ns::A x; }
38};
39}
40
41namespace enclosing_friend_no_tag {
42struct B;
43namespace ns {
44struct A {
45  friend B; // Removing the tag decl fixes it.
46protected:
47  A();
48};
49}
50struct B {
51  static void f() { ns::A x; }
52};
53}
54
55namespace enclosing_friend_func {
56void f();
57namespace ns {
58struct A {
59  // Amusingly, in MSVC, this declares ns::f(), and doesn't find the outer f().
60  friend void f();
61protected:
62  A(); // expected-note {{declared protected here}}
63};
64}
65void f() { ns::A x; } // expected-error {{calling a protected constructor of class 'enclosing_friend_func::ns::A'}}
66}
67
68namespace test_nns_fixit_hint {
69namespace name1 {
70namespace name2 {
71struct X;
72struct name2;
73namespace name3 {
74struct 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.
85namespace friend_as_a_forward_decl {
86
87class A {
88  class Nested {
89    friend class B;
90    B *b;
91  };
92  B *b;
93};
94B *global_b;
95
96void f() {
97  class Local {
98    friend class Z;
99    Z *b;
100  };
101  Z *b;
102}
103
104}
105