]> granicus.if.org Git - clang/commitdiff
Parse base specifiers within the scope of the class. This is possibly not
authorJohn McCall <rjmccall@apple.com>
Sat, 19 Dec 2009 21:48:58 +0000 (21:48 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 19 Dec 2009 21:48:58 +0000 (21:48 +0000)
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
lib/Parse/ParseDeclCXX.cpp
test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp [new file with mode: 0644]

index bf188cf14f9111d3ad765a19b6ee6aaf926535d8..98a74a5a03952a2560d2b1b75167dc51809c6af4 100644 (file)
@@ -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">;
index d4d19a0b076566d73077fb73d4ec63fac14ccc40..fcbbce1062dfb6c71e76befd5ee78ead31e0e778 100644 (file)
@@ -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 (file)
index 0000000..f22e4a4
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5741
+struct A {
+  struct B { };
+  struct C;
+};
+
+struct A::C : B { };