From: Anders Carlsson Date: Wed, 6 May 2009 04:46:28 +0000 (+0000) Subject: Add parsing of friend specifiers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f47f7a1c4082b42b21f1c7dc211ff90f4b38258a;p=clang Add parsing of friend specifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71067 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index e97c20f2d1..fad3f1e676 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -123,6 +123,9 @@ private: bool FS_virtual_specified : 1; bool FS_explicit_specified : 1; + // friend-specifier + bool Friend_specified : 1; + /// TypeRep - This contains action-specific information about a specific TST. /// For example, for a typedef or struct, it might contain the declaration for /// these. @@ -145,6 +148,7 @@ private: SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; + SourceLocation FriendLoc; bool BadSpecifier(TST T, const char *&PrevSpec); bool BadSpecifier(TQ T, const char *&PrevSpec); @@ -168,6 +172,7 @@ public: FS_inline_specified(false), FS_virtual_specified(false), FS_explicit_specified(false), + Friend_specified(false), TypeRep(0), AttrList(0), ProtocolQualifiers(0), @@ -277,6 +282,8 @@ public: bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec); bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec); + bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec); + /// AddAttributes - contatenates two attribute lists. /// The GCC attribute syntax allows for the following: /// diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index d742ef2ed0..e592deecd0 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -294,6 +294,16 @@ bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec return false; } +bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec) { + if (Friend_specified) { + PrevSpec = "friend"; + return true; + } + + Friend_specified = true; + FriendLoc = Loc; + return false; +} /// Finish - This does final analysis of the declspec, rejecting things like /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 8b81c312d2..b3c2d8c555 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -597,6 +597,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, /// [C99] 'inline' /// [C++] 'virtual' /// [C++] 'explicit' +/// 'friend': [C++ dcl.friend] + /// void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, TemplateParameterLists *TemplateParams, @@ -846,6 +848,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec); break; + // friend + case tok::kw_friend: + isInvalid = DS.SetFriendSpec(Loc, PrevSpec); + break; + // type-specifier case tok::kw_short: isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp new file mode 100644 index 0000000000..5bfaf2fdbc --- /dev/null +++ b/test/Parser/cxx-friend.cpp @@ -0,0 +1,5 @@ +// RUN: clang-cc -fsyntax-only %s + +class C { + friend class D; +};