Home | History | Annotate | Download | only in SemaCXX
      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