diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 7 | ||||
| -rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Parser/cxx-friend.cpp | 5 |
4 files changed, 29 insertions, 0 deletions
diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index e97c20f2d19..fad3f1e6768 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/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/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index d742ef2ed09..e592deecd04 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/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/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 8b81c312d2e..b3c2d8c5556 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/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/clang/test/Parser/cxx-friend.cpp b/clang/test/Parser/cxx-friend.cpp new file mode 100644 index 00000000000..5bfaf2fdbce --- /dev/null +++ b/clang/test/Parser/cxx-friend.cpp @@ -0,0 +1,5 @@ +// RUN: clang-cc -fsyntax-only %s + +class C { + friend class D; +}; |

