"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<
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);
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);
--- /dev/null
+// 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}}