diff options
author | John McCall <rjmccall@apple.com> | 2009-08-06 02:15:43 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-08-06 02:15:43 +0000 |
commit | 67d1a67f3db2f1aa69083c5c94164d6e0ee05b32 (patch) | |
tree | 7a033d2138cdd888dc7e6c88b60bd6ae8b43f8bf /lib/Parse/ParseDeclCXX.cpp | |
parent | 32d96b08dbfb6fbe88d74a9a85aad200ceae656a (diff) |
First pass at friend semantics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78274 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index c0df8a59f7..5084d8a831 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -567,15 +567,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } } - // There are three options here. If we have 'struct foo;', then - // this is a forward declaration. If we have 'struct foo {...' or + // There are four options here. If we have 'struct foo;', then this + // is either a forward declaration or a friend declaration, which + // have to be treated differently. If we have 'struct foo {...' or // 'struct foo :...' then this is a definition. Otherwise we have // something like 'struct foo xyz', a reference. Action::TagUseKind TUK; if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) TUK = Action::TUK_Definition; - else if (Tok.is(tok::semi) && !DS.isFriendSpecified()) - TUK = Action::TUK_Declaration; + else if (Tok.is(tok::semi)) + TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration; else TUK = Action::TUK_Reference; @@ -600,7 +601,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // to turn that template-id into a type. bool Owned = false; - if (TemplateId && TUK != Action::TUK_Reference) { + if (TemplateId && TUK != Action::TUK_Reference && TUK != Action::TUK_Friend) { // Explicit specialization, class template partial specialization, // or explicit instantiation. ASTTemplateArgsPtr TemplateArgsPtr(Actions, @@ -727,10 +728,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, DiagID, TagOrTempResult.get().getAs<void>(), Owned)) Diag(StartLoc, DiagID) << PrevSpec; - - if (DS.isFriendSpecified()) - Actions.ActOnFriendDecl(CurScope, DS.getFriendSpecLoc(), - TagOrTempResult.get()); } /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. @@ -951,24 +948,17 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { // decl-specifier-seq: // Parse the common declaration-specifiers piece. DeclSpec DS; - ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS); + ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_class); if (Tok.is(tok::semi)) { ConsumeToken(); - // C++ 9.2p7: The member-declarator-list can be omitted only after a - // class-specifier or an enum-specifier or in a friend declaration. - // FIXME: Friend declarations. - switch (DS.getTypeSpecType()) { - case DeclSpec::TST_struct: - case DeclSpec::TST_union: - case DeclSpec::TST_class: - case DeclSpec::TST_enum: + + if (DS.isFriendSpecified()) + Actions.ActOnFriendDecl(CurScope, &DS); + else Actions.ParsedFreeStandingDeclSpec(CurScope, DS); - return; - default: - Diag(DSStart, diag::err_no_declarators); - return; - } + + return; } Declarator DeclaratorInfo(DS, Declarator::MemberContext); @@ -1066,11 +1056,17 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { // NOTE: If Sema is the Action module and declarator is an instance field, // this call will *not* return the created decl; It will return null. // See Sema::ActOnCXXMemberDeclarator for details. - DeclPtrTy ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS, - DeclaratorInfo, - BitfieldSize.release(), - Init.release(), - Deleted); + + DeclPtrTy ThisDecl; + if (DS.isFriendSpecified()) { + // TODO: handle initializers, bitfields, 'delete' + ThisDecl = Actions.ActOnFriendDecl(CurScope, &DeclaratorInfo); + } else + ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS, + DeclaratorInfo, + BitfieldSize.release(), + Init.release(), + Deleted); if (ThisDecl) DeclsInGroup.push_back(ThisDecl); |