Author: dgregor Date: Mon Jun 21 17:31:09 2010 New Revision: 106496 URL: http://llvm.org/viewvc/llvm-project?rev=106496&view=rev Log: 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 <rdar://problem/8104754>.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=106496&r1=106495&r2=106496&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jun 21 17:31:09 2010 @@ -1563,40 +1563,45 @@ 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. - - // 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; - } + 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; + } - 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); + } - SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); + RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); + } else { + SkipUntil(tok::r_brace, false, false); + } // If attributes exist after class contents, parse them. llvm::OwningPtr<AttributeList> AttrList; @@ -1615,7 +1620,7 @@ // // 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. _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits