blob: c63160f5b9f9cb688f6cd47d5a38bd9c76f55c32 [file] [log] [blame]
Reid Kleckner0902a512014-07-10 23:44:52 +00001// 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}