aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-19 21:48:58 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-19 21:48:58 +0000
commitbd0dfa5c37d422427080a0ae3af9b63e70e6e854 (patch)
tree90d8a20362104d591ac022b2266c00b6e3270d5b
parentc5a857fa5619be83e9154c966db6123724fb3c9e (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--lib/Parse/ParseDeclCXX.cpp30
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp9
3 files changed, 29 insertions, 12 deletions
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 { };