From f83c9faa2fe6f2f02bcad24fd1650e53acbfe772 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 11 May 2009 22:27:47 +0000 Subject: [PATCH] Add an ActOnFriendDecl and call it for friend class decls. llvm-svn: 71482 --- clang/include/clang/Parse/Action.h | 7 +++++++ clang/include/clang/Parse/DeclSpec.h | 1 + clang/lib/Parse/ParseDeclCXX.cpp | 14 +++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index f70c9f05915e..f41e465fe0d6 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -933,6 +933,13 @@ public: return DeclPtrTy(); } + /// ActOnFriendDecl - This action is called when a friend declaration is + /// encountered. Returns false on success. + virtual bool ActOnFriendDecl(Scope *S, SourceLocation FriendLoc, + DeclPtrTy Dcl) { + return false; + } + //===------------------------- C++ Expressions --------------------------===// diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index 9528298109a2..efb7d65c2df5 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -284,6 +284,7 @@ public: bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec); bool isFriendSpecified() const { return Friend_specified; } + SourceLocation getFriendSpecLoc() const { return FriendLoc; } /// AddAttributes - contatenates two attribute lists. /// The GCC attribute syntax allows for the following: diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index e1e81ec33d3e..da99ab9aa2df 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -525,10 +525,18 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } const char *PrevSpec = 0; - if (TagOrTempResult.isInvalid()) + if (TagOrTempResult.isInvalid()) { DS.SetTypeSpecError(); - else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, - TagOrTempResult.get().getAs())) + return; + } + + if (DS.isFriendSpecified() && + !Actions.ActOnFriendDecl(CurScope, DS.getFriendSpecLoc(), + TagOrTempResult.get())) + return; + + if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, + TagOrTempResult.get().getAs())) Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; }