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