diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-06-21 22:31:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-06-21 22:31:09 +0000 |
commit | 07976d25eda0fed2734518be022ee84fab898cc6 (patch) | |
tree | b7a950f491e55d68dd710b839ab37309857de005 /lib/Parse/ParseDeclCXX.cpp | |
parent | e437baccbeb1b69ca9cc3f3d053b0543e28d4681 (diff) |
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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106496 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 65 |
1 files changed, 35 insertions, 30 deletions
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<AttributeList> 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. |