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