diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-12 08:56:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-12 08:56:40 +0000 |
commit | 7796eb5643244f3134834253ce5ea89107ac21c1 (patch) | |
tree | 223c93c51604d1e6128470ad42ea5af267b8abaf /lib/Parse/ParseDecl.cpp | |
parent | 69730c115c2d0fec2f20609d905d920a5a41b29b (diff) |
Fix parsing of trailing-return-type. Types are syntactically prohibited from
being defined here: [] () -> struct S {} does not define struct S.
In passing, implement DR1318 (syntactic disambiguation of 'final').
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152551 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c1f6eb5d42..31a898cf5a 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -36,9 +36,13 @@ TypeResult Parser::ParseTypeName(SourceRange *Range, Declarator::TheContext Context, AccessSpecifier AS, Decl **OwnedType) { + DeclSpecContext DSC = DSC_normal; + if (Context == Declarator::TrailingReturnContext) + DSC = DSC_trailing; + // Parse the common declaration-specifiers piece. DeclSpec DS(AttrFactory); - ParseSpecifierQualifierList(DS, AS); + ParseSpecifierQualifierList(DS, AS, DSC); if (OwnedType) *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0; @@ -2653,8 +2657,12 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, while (Tok.is(tok::kw___declspec)) ParseMicrosoftDeclSpec(attrs); - bool AllowFixedUnderlyingType - = getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt || getLangOpts().ObjC2; + // Enum definitions should not be parsed in a trailing-return-type. + bool AllowDeclaration = DSC != DSC_trailing; + + bool AllowFixedUnderlyingType = AllowDeclaration && + (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt || + getLangOpts().ObjC2); CXXScopeSpec &SS = DS.getTypeSpecScope(); if (getLangOpts().CPlusPlus) { @@ -2679,7 +2687,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // Must have either 'enum name' or 'enum {...}'. if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && - (AllowFixedUnderlyingType && Tok.isNot(tok::colon))) { + !(AllowFixedUnderlyingType && Tok.is(tok::colon))) { Diag(Tok, diag::err_expected_ident_lbrace); // Skip the rest of this declarator, up until the comma or semicolon. @@ -2785,6 +2793,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, Sema::TagUseKind TUK; if (DS.isFriendSpecified()) TUK = Sema::TUK_Friend; + else if (!AllowDeclaration) + TUK = Sema::TUK_Reference; else if (Tok.is(tok::l_brace)) TUK = Sema::TUK_Definition; else if (Tok.is(tok::semi) && DSC != DSC_type_specifier) @@ -2850,7 +2860,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (!TagDecl) { // The action failed to produce an enumeration tag. If this is a // definition, consume the entire definition. - if (Tok.is(tok::l_brace)) { + if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { ConsumeBrace(); SkipUntil(tok::r_brace); } @@ -2859,7 +2869,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, return; } - if (Tok.is(tok::l_brace)) { + if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { if (TUK == Sema::TUK_Friend) Diag(Tok, diag::err_friend_decl_defines_type) << SourceRange(DS.getFriendSpecLoc()); |