summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-05-11 22:55:49 +0000
committerAnders Carlsson <andersca@mac.com>2009-05-11 22:55:49 +0000
commit388117089899a3e27a24f2f7f5cfa64255ca4d08 (patch)
treec4d76e8fbae0ae538c5ad2cf3f80c599c26a1832 /clang
parent97f75f8bda68999d91c637da62cc83260cfb7a4d (diff)
downloadbcm5719-llvm-388117089899a3e27a24f2f7f5cfa64255ca4d08.tar.gz
bcm5719-llvm-388117089899a3e27a24f2f7f5cfa64255ca4d08.zip
Friend declarations are only valid inside class definitions.
llvm-svn: 71489
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--clang/test/SemaCXX/friend.cpp6
4 files changed, 21 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 577392cbd60..aaaad13b128 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 7a25fa9668d..21aca40c7d2 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -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);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7e91f5beac9..726080b7ff6 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp
new file mode 100644
index 00000000000..76e84e5fbe8
--- /dev/null
+++ b/clang/test/SemaCXX/friend.cpp
@@ -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}}
OpenPOWER on IntegriCloud