diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-02-03 21:21:43 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-02-03 21:21:43 +0000 |
commit | d9bafa76f8d6eb9e4f4974ed322217f8df6bb82e (patch) | |
tree | 9cf872e4c9dda96f96407751cc0e07a322074121 /lib/Parse/ParseDeclCXX.cpp | |
parent | 3d0ad58b28e0d50fca7f21c6a078b05370510288 (diff) |
In some contexts, type declarations cannot occur. Pass this information down to ParseClassSpecifier, to make its decision easier. Fixes PR6200.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95255 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index f95fedc4e3..07bae1c7a4 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -547,7 +547,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which /// until we reach the start of a definition or see a token that -/// cannot start a definition. +/// cannot start a definition. If SuppressDeclarations is true, we do know. /// /// class-specifier: [C++ class] /// class-head '{' member-specification[opt] '}' @@ -587,7 +587,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation StartLoc, DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, - AccessSpecifier AS) { + AccessSpecifier AS, bool SuppressDeclarations){ DeclSpec::TST TagType; if (TagTokKind == tok::kw_struct) TagType = DeclSpec::TST_struct; @@ -733,8 +733,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // 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. + // However, in some contexts, things look like declarations but are just + // references, e.g. + // new struct s; + // or + // &T::operator struct s; + // For these, SuppressDeclarations is true. Action::TagUseKind TUK; - if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) { + if (SuppressDeclarations) + TUK = Action::TUK_Reference; + else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){ if (DS.isFriendSpecified()) { // C++ [class.friend]p2: // A class shall not be defined in a friend declaration. |