]> granicus.if.org Git - clang/commitdiff
Friend declarations are only valid inside class definitions.
authorAnders Carlsson <andersca@mac.com>
Mon, 11 May 2009 22:55:49 +0000 (22:55 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 11 May 2009 22:55:49 +0000 (22:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71489 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/friend.cpp [new file with mode: 0644]

index 577392cbd60bfe3fb15f71be080146658afe898c..aaaad13b1289ca9eaf3c47339966144527df1c53 100644 (file)
@@ -243,6 +243,9 @@ def err_static_assert_expression_is_not_constant : Error<
   "static_assert expression is not an integral constant expression">;
 def err_static_assert_failed : Error<"static_assert failed \"%0\"">;
 
+def err_friend_decl_outside_class : Error<
+  "'friend' used outside of class">;
+
 def err_abstract_type_in_decl : Error<
   "%select{return|parameter|variable|field}1 type %0 is an abstract class">;
 def err_allocation_of_abstract_type : Error<
index 7a25fa9668d58b1f67fc1c6a0217da1051ba35e5..21aca40c7d259fee8f495a66c2b510770ff94b9b 100644 (file)
@@ -1731,6 +1731,9 @@ public:
                                                  ExprArg AssertExpr,
                                                  ExprArg AssertMessageExpr);
   
+  virtual bool ActOnFriendDecl(Scope *S, SourceLocation FriendLoc,
+                               DeclPtrTy Dcl);
+
   QualType CheckConstructorDeclarator(Declarator &D, QualType R,
                                       FunctionDecl::StorageClass& SC);
   void CheckConstructor(CXXConstructorDecl *Constructor);
index 7e91f5beac9b1b03131af386e52d918c860be642..726080b7ff60a595da05b1b40f364cfd7243b927 100644 (file)
@@ -2643,6 +2643,15 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
   return DeclPtrTy::make(Decl);
 }
 
+bool Sema::ActOnFriendDecl(Scope *S, SourceLocation FriendLoc, DeclPtrTy Dcl) {
+  if (!(S->getFlags() & Scope::ClassScope)) {
+    Diag(FriendLoc, diag::err_friend_decl_outside_class);
+    return true;
+  }
+  
+  return false;
+}
+
 void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
   Decl *Dcl = dcl.getAs<Decl>();
   FunctionDecl *Fn = dyn_cast<FunctionDecl>(Dcl);
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
new file mode 100644 (file)
index 0000000..76e84e5
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+friend class A; // expected-error {{'friend' used outside of class}}
+void f() { friend class A; } // expected-error {{'friend' used outside of class}}
+class C { friend class A; };
+class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}}