From bd0dfa5c37d422427080a0ae3af9b63e70e6e854 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 19 Dec 2009 21:48:58 +0000 Subject: [PATCH] Parse base specifiers within the scope of the class. This is possibly not quite right; I'll come back to it later. It does fix PR 5741. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91789 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 ++ lib/Parse/ParseDeclCXX.cpp | 30 +++++++++++-------- .../basic.lookup/basic.lookup.unqual/p7.cpp | 9 ++++++ 3 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index bf188cf14f..98a74a5a03 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -229,6 +229,8 @@ def warn_parens_disambiguated_as_function_decl : Warning< "parentheses were disambiguated as a function declarator">; def err_expected_member_or_base_name : Error< "expected class member or base class name">; +def err_expected_lbrace_after_base_specifiers : Error< + "expected '{' after base class list">; def ext_ellipsis_exception_spec : Extension< "exception specification of '...' is a Microsoft extension">; def err_expected_catch : Error<"expected catch">; diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d4d19a0b07..fcbbce1062 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -852,20 +852,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, SS, Name, StartLoc, NameLoc); } - // Parse the optional base clause (C++ only). - if (getLang().CPlusPlus && Tok.is(tok::colon)) - ParseBaseClause(TagOrTempResult.get()); - // If there is a body, parse it and inform the actions module. - if (Tok.is(tok::l_brace)) + if (TUK == Action::TUK_Definition) { + assert(Tok.is(tok::l_brace) || + (getLang().CPlusPlus && Tok.is(tok::colon))); if (getLang().CPlusPlus) ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get()); else ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); - else if (TUK == Action::TUK_Definition) { - // FIXME: Complain that we have a base-specifier list but no - // definition. - Diag(Tok, diag::err_expected_lbrace); } void *Result; @@ -1364,8 +1358,6 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, PP.getSourceManager(), "parsing struct/union/class body"); - SourceLocation LBraceLoc = ConsumeBrace(); - // Determine whether this is a top-level (non-nested) class. bool TopLevelClass = ClassStack.empty() || CurScope->isInCXXInlineMethodScope(); @@ -1378,7 +1370,21 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (TagDecl) Actions.ActOnTagStartDefinition(CurScope, TagDecl); - else { + + if (Tok.is(tok::colon)) { + ParseBaseClause(TagDecl); + + if (!Tok.is(tok::l_brace)) { + Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); + return; + } + } + + assert(Tok.is(tok::l_brace)); + + SourceLocation LBraceLoc = ConsumeBrace(); + + if (!TagDecl) { SkipUntil(tok::r_brace, false, false); return; } diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp new file mode 100644 index 0000000000..f22e4a467e --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5741 +struct A { + struct B { }; + struct C; +}; + +struct A::C : B { }; -- 2.40.0