From: Douglas Gregor Date: Mon, 21 Jun 2010 22:31:09 +0000 (+0000) Subject: When semantic analysis fail to introduce a class or class template, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07976d25eda0fed2734518be022ee84fab898cc6;p=clang When semantic analysis fail to introduce a class or class template, just skip over the body of the class or class template: it's a semantic disaster that's likely to cause invariants to break. Fixes part of . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106496 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index bfc5b05e73..53fc3405bb 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1563,41 +1563,46 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, else CurAS = AS_public; - // While we still have something to read, read the member-declarations. - while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { - // Each iteration of this loop reads one member-declaration. + SourceLocation RBraceLoc; + if (TagDecl) { + // While we still have something to read, read the member-declarations. + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { + // Each iteration of this loop reads one member-declaration. + + // Check for extraneous top-level semicolon. + if (Tok.is(tok::semi)) { + Diag(Tok, diag::ext_extra_struct_semi) + << DeclSpec::getSpecifierName((DeclSpec::TST)TagType) + << FixItHint::CreateRemoval(Tok.getLocation()); + ConsumeToken(); + continue; + } - // Check for extraneous top-level semicolon. - if (Tok.is(tok::semi)) { - Diag(Tok, diag::ext_extra_struct_semi) - << DeclSpec::getSpecifierName((DeclSpec::TST)TagType) - << FixItHint::CreateRemoval(Tok.getLocation()); - ConsumeToken(); - continue; - } + AccessSpecifier AS = getAccessSpecifierIfPresent(); + if (AS != AS_none) { + // Current token is a C++ access specifier. + CurAS = AS; + SourceLocation ASLoc = Tok.getLocation(); + ConsumeToken(); + if (Tok.is(tok::colon)) + Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); + else + Diag(Tok, diag::err_expected_colon); + ConsumeToken(); + continue; + } - AccessSpecifier AS = getAccessSpecifierIfPresent(); - if (AS != AS_none) { - // Current token is a C++ access specifier. - CurAS = AS; - SourceLocation ASLoc = Tok.getLocation(); - ConsumeToken(); - if (Tok.is(tok::colon)) - Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); - else - Diag(Tok, diag::err_expected_colon); - ConsumeToken(); - continue; - } + // FIXME: Make sure we don't have a template here. - // FIXME: Make sure we don't have a template here. + // Parse all the comma separated declarators. + ParseCXXClassMemberDeclaration(CurAS); + } - // Parse all the comma separated declarators. - ParseCXXClassMemberDeclaration(CurAS); + RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); + } else { + SkipUntil(tok::r_brace, false, false); } - SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - // If attributes exist after class contents, parse them. llvm::OwningPtr AttrList; if (Tok.is(tok::kw___attribute)) @@ -1615,7 +1620,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // // FIXME: Only function bodies and constructor ctor-initializers are // parsed correctly, fix the rest. - if (NonNestedClass) { + if (TagDecl && NonNestedClass) { // We are not inside a nested class. This class and its nested classes // are complete and we can parse the delayed portions of method // declarations and the lexed inline method definitions.