On Mon, Mar 12, 2012 at 9:24 AM, David Blaikie <[email protected]> wrote:
> On Mon, Mar 12, 2012 at 1:56 AM, Richard Smith > <[email protected]> wrote: > > Author: rsmith > > Date: Mon Mar 12 03:56:40 2012 > > New Revision: 152551 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=152551&view=rev > > Log: > > 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'). > > > > Modified: > > cfe/trunk/include/clang/Parse/Parser.h > > cfe/trunk/include/clang/Sema/DeclSpec.h > > cfe/trunk/lib/Parse/ParseDecl.cpp > > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > > cfe/trunk/lib/Sema/SemaType.cpp > > cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp > > cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp > > cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp > > cfe/trunk/test/Parser/cxx0x-ambig.cpp > > cfe/trunk/test/Parser/cxx0x-decl.cpp > > cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp > > > > Modified: cfe/trunk/include/clang/Parse/Parser.h > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=152551&r1=152550&r2=152551&view=diff > > > ============================================================================== > > --- cfe/trunk/include/clang/Parse/Parser.h (original) > > +++ cfe/trunk/include/clang/Parse/Parser.h Mon Mar 12 03:56:40 2012 > > @@ -1622,6 +1622,7 @@ > > DSC_normal, // normal context > > DSC_class, // class context, enables 'friend' > > DSC_type_specifier, // C++ type-specifier-seq > > + DSC_trailing, // C++11 trailing-type-specifier in a trailing return > type > > DSC_top_level // top-level/namespace declaration context > > }; > > > > > > Modified: cfe/trunk/include/clang/Sema/DeclSpec.h > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=152551&r1=152550&r2=152551&view=diff > > > ============================================================================== > > --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) > > +++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon Mar 12 03:56:40 2012 > > @@ -1428,9 +1428,10 @@ > > ObjCCatchContext, // Objective-C catch exception-declaration > > BlockLiteralContext, // Block literal declarator. > > LambdaExprContext, // Lambda-expression declarator. > > + TrailingReturnContext, // C++11 trailing-type-specifier. > > TemplateTypeArgContext, // Template type argument. > > - AliasDeclContext, // C++0x alias-declaration. > > - AliasTemplateContext // C++0x alias-declaration template. > > + AliasDeclContext, // C++11 alias-declaration. > > + AliasTemplateContext // C++11 alias-declaration template. > > }; > > > > private: > > @@ -1604,6 +1605,7 @@ > > case BlockLiteralContext: > > case LambdaExprContext: > > case TemplateTypeArgContext: > > + case TrailingReturnContext: > > return true; > > } > > llvm_unreachable("unknown context kind!"); > > @@ -1635,6 +1637,7 @@ > > case BlockLiteralContext: > > case LambdaExprContext: > > case TemplateTypeArgContext: > > + case TrailingReturnContext: > > return false; > > } > > llvm_unreachable("unknown context kind!"); > > @@ -1679,6 +1682,7 @@ > > case BlockLiteralContext: > > case LambdaExprContext: > > case TemplateTypeArgContext: > > + case TrailingReturnContext: > > return false; > > } > > llvm_unreachable("unknown context kind!"); > > > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=152551&r1=152550&r2=152551&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Mar 12 03:56:40 2012 > > @@ -36,9 +36,13 @@ > > 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 @@ > > 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 @@ > > > > // 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 @@ > > 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 @@ > > 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 @@ > > 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()); > > > > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=152551&r1=152550&r2=152551&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) > > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Mar 12 03:56:40 2012 > > @@ -1114,11 +1114,16 @@ > > if (SuppressingAccessChecks) > > Actions.ActOnStopSuppressingAccessChecks(); > > > > - // 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 {...', > > - // 'struct foo :...' or 'struct foo final[opt]' then this is a > > - // definition. Otherwise we have something like 'struct foo xyz', a > reference. > > + // There are four options here. > > + // - If we are in a trailing return type, this is always just a > reference, > > + // and we must not try to parse a definition. For instance, > > + // [] () -> struct S { }; > > + // does not define a type. > > + // - If we have 'struct foo {...', 'struct foo :...', > > + // 'struct foo final :' or 'struct foo final {', then this is a > definition. > > + // - If we have 'struct foo;', then this is either a forward > declaration > > + // or a friend declaration, which have to be treated differently. > > + // - Otherwise we have something like 'struct foo xyz', a reference. > > // However, in type-specifier-seq's, things look like declarations but > are > > // just references, e.g. > > // new struct s; > > @@ -1126,10 +1131,12 @@ > > // &T::operator struct s; > > // For these, DSC is DSC_type_specifier. > > Sema::TagUseKind TUK; > > - if (Tok.is(tok::l_brace) || > > - (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || > > - // FIXME: 'final' must be followed by ':' or '{' to mark a > definition. > > - isCXX0XFinalKeyword()) { > > + if (DSC == DSC_trailing) > > + TUK = Sema::TUK_Reference; > > + else if (Tok.is(tok::l_brace) || > > + (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || > > + (isCXX0XFinalKeyword() && > > + NextToken().is(tok::l_brace) || > NextToken().is(tok::colon))) { > > This caused a -Wlogical-op-parentheses warning which caught a > crash-on-invalid (perhaps there are valid cases too, but the simple > case I tested (where the current token is 'foo', not 'final' and is > followed by a colon) was invalid). I fixed this & included the test > case in r152559. For completeness we could add a test case for the > reverse (the case where the brace and colon tests were switched around > & produced the same sort of bug) but I didn't bother. Oops, thanks!
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
