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