forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -verify
 | |
| // RUN: not %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
 | |
| 
 | |
| struct X;
 | |
| namespace name_at_tu_scope {
 | |
| struct Y {
 | |
|   friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
 | |
|   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"::"
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace enclosing_friend_decl {
 | |
| struct B;
 | |
| namespace ns {
 | |
| struct A {
 | |
|   friend struct B; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
 | |
|   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"enclosing_friend_decl::"
 | |
| protected:
 | |
|   A();
 | |
| };
 | |
| }
 | |
| struct B {
 | |
|   static void f() { ns::A x; }
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace enclosing_friend_qualified {
 | |
| struct B;
 | |
| namespace ns {
 | |
| struct A {
 | |
|   friend struct enclosing_friend_qualified::B; // Adding name specifiers fixes it.
 | |
| protected:
 | |
|   A();
 | |
| };
 | |
| }
 | |
| struct B {
 | |
|   static void f() { ns::A x; }
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace enclosing_friend_no_tag {
 | |
| struct B;
 | |
| namespace ns {
 | |
| struct A {
 | |
|   friend B; // Removing the tag decl fixes it.
 | |
| protected:
 | |
|   A();
 | |
| };
 | |
| }
 | |
| struct B {
 | |
|   static void f() { ns::A x; }
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace enclosing_friend_func {
 | |
| void f();
 | |
| namespace ns {
 | |
| struct A {
 | |
|   // Amusingly, in MSVC, this declares ns::f(), and doesn't find the outer f().
 | |
|   friend void f();
 | |
| protected:
 | |
|   A(); // expected-note {{declared protected here}}
 | |
| };
 | |
| }
 | |
| void f() { ns::A x; } // expected-error {{calling a protected constructor of class 'enclosing_friend_func::ns::A'}}
 | |
| }
 | |
| 
 | |
| namespace test_nns_fixit_hint {
 | |
| namespace name1 {
 | |
| namespace name2 {
 | |
| struct X;
 | |
| struct name2;
 | |
| namespace name3 {
 | |
| struct Y {
 | |
|   friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
 | |
|   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"name1::name2::"
 | |
| };
 | |
| }
 | |
| }
 | |
| }
 | |
| }
 | |
| 
 | |
| // A friend declaration injects a forward declaration into the nearest enclosing
 | |
| // non-member scope.
 | |
| namespace friend_as_a_forward_decl {
 | |
| 
 | |
| class A {
 | |
|   class Nested {
 | |
|     friend class B;
 | |
|     B *b;
 | |
|   };
 | |
|   B *b;
 | |
| };
 | |
| B *global_b;
 | |
| 
 | |
| void f() {
 | |
|   class Local {
 | |
|     friend class Z;
 | |
|     Z *b;
 | |
|   };
 | |
|   Z *b;
 | |
| }
 | |
| 
 | |
| }
 |