[cfe-commits] r140847 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseTemplate.cpp test/Parser/cxx-member-initializers.cpp test/Parser/cxx0x-member-initializers.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Fri Sep 30 01:32:19 PDT 2011


Author: cornedbee
Date: Fri Sep 30 03:32:17 2011
New Revision: 140847

URL: http://llvm.org/viewvc/llvm-project?rev=140847&view=rev
Log:
Fix a bug in the token caching for inline constructors in C++11, and improve error recovery in both dialects. This should fix the GCC test suite failures as well.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/test/Parser/cxx-member-initializers.cpp
    cfe/trunk/test/Parser/cxx0x-member-initializers.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=140847&r1=140846&r2=140847&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Sep 30 03:32:17 2011
@@ -1060,7 +1060,7 @@
   void ParseLexedMemberInitializers(ParsingClass &Class);
   void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
   Decl *ParseLexedObjCMethodDefs(LexedMethod &LM);
-  bool ConsumeAndStoreTryAndInitializers(CachedTokens &Toks);
+  bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
   bool ConsumeAndStoreUntil(tok::TokenKind T1,
                             CachedTokens &Toks,
                             bool StopAtSemi = true,

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=140847&r1=140846&r2=140847&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Fri Sep 30 03:32:17 2011
@@ -123,31 +123,24 @@
   CachedTokens &Toks = LM->Toks;
 
   tok::TokenKind kind = Tok.getKind();
-  // We may have a constructor initializer or function-try-block here.
-  if (kind == tok::colon || kind == tok::kw_try) {
-    // Consume everything up to (and including) the left brace of the
-    // function body.
-    if (ConsumeAndStoreTryAndInitializers(Toks)) {
-      // We didn't find the left-brace we expected after the
-      // constructor initializer.
-      if (Tok.is(tok::semi)) {
-        // We found a semicolon; complain, consume the semicolon, and
-        // don't try to parse this method later.
-        Diag(Tok.getLocation(), diag::err_expected_lbrace);
-        ConsumeAnyToken();
-        delete getCurrentClass().LateParsedDeclarations.back();
-        getCurrentClass().LateParsedDeclarations.pop_back();
-        return FnD;
-      }
+  // Consume everything up to (and including) the left brace of the
+  // function body.
+  if (ConsumeAndStoreFunctionPrologue(Toks)) {
+    // We didn't find the left-brace we expected after the
+    // constructor initializer.
+    if (Tok.is(tok::semi)) {
+      // We found a semicolon; complain, consume the semicolon, and
+      // don't try to parse this method later.
+      Diag(Tok.getLocation(), diag::err_expected_lbrace);
+      ConsumeAnyToken();
+      delete getCurrentClass().LateParsedDeclarations.back();
+      getCurrentClass().LateParsedDeclarations.pop_back();
+      return FnD;
     }
-
   } else {
-    // Begin by storing the '{' token.
-    Toks.push_back(Tok);
-    ConsumeBrace();
+    // Consume everything up to (and including) the matching right brace.
+    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
   }
-  // Consume everything up to (and including) the matching right brace.
-  ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
 
   // If we're in a function-try-block, we need to store all the catch blocks.
   if (kind == tok::kw_try) {
@@ -583,10 +576,11 @@
 
 /// \brief Consume tokens and store them in the passed token container until
 /// we've passed the try keyword and constructor initializers and have consumed
-/// the opening brace of the function body.
+/// the opening brace of the function body. The opening brace will be consumed
+/// if and only if there was no error.
 ///
-/// \return True on error.
-bool Parser::ConsumeAndStoreTryAndInitializers(CachedTokens &Toks) {
+/// \return True on error. 
+bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
   if (Tok.is(tok::kw_try)) {
     Toks.push_back(Tok);
     ConsumeToken();
@@ -613,6 +607,10 @@
       else {
         assert(kind == tok::l_brace && "Must be left paren or brace here.");
         ConsumeBrace();
+        // In C++03, this has to be the start of the function body, which
+        // means the initializer is malformed.
+        if (!getLang().CPlusPlus0x)
+          return false;
       }
 
       // Grab the initializer
@@ -620,10 +618,25 @@
                                                        tok::r_brace,
                                 Toks, /*StopAtSemi=*/true))
         return true;
+
+      // Grab the separating comma, if any.
+      if (Tok.is(tok::comma)) {
+        Toks.push_back(Tok);
+        ConsumeToken();
+      }
     }
   }
 
-  // Grab any remaining garbage to be diagnosed later, and the opening
-  // brace of the function body.
-  return !ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/true);
+  // Grab any remaining garbage to be diagnosed later. We stop when we reach a
+  // brace: an opening one is the function body, while a closing one probably
+  // means we've reached the end of the class.
+  if (!ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
+                            /*StopAtSemi=*/true, /*ConsumeFinalToken=*/false))
+    return true;
+  if(Tok.isNot(tok::l_brace))
+    return true;
+
+  Toks.push_back(Tok);
+  ConsumeBrace();
+  return false;
 }

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=140847&r1=140846&r2=140847&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri Sep 30 03:32:17 2011
@@ -1181,13 +1181,13 @@
     for (; II != DeclContextToReenter.rend(); ++II) {
       if (ClassTemplatePartialSpecializationDecl* MD =
                 dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
-       TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                   Scope::TemplateParamScope));
+       TemplateParamScopeStack.push_back(new ParseScope(this,
+                                                   Scope::TemplateParamScope));
         Actions.ActOnReenterTemplateScope(getCurScope(), MD);
       } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
-        TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                    Scope::TemplateParamScope,
-                                       MD->getDescribedClassTemplate() != 0 ));
+        TemplateParamScopeStack.push_back(new ParseScope(this,
+                                                    Scope::TemplateParamScope,
+                                       MD->getDescribedClassTemplate() != 0 ));
         Actions.ActOnReenterTemplateScope(getCurScope(),
                                           MD->getDescribedClassTemplate());
       }
@@ -1250,15 +1250,10 @@
 /// \brief Lex a delayed template function for late parsing.
 void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
   tok::TokenKind kind = Tok.getKind();
-  // We may have a constructor initializer or function-try-block here.
-  if (kind == tok::colon || kind == tok::kw_try)
-    ConsumeAndStoreTryAndInitializers(Toks);
-  else {
-    Toks.push_back(Tok);
-    ConsumeBrace();
+  if (!ConsumeAndStoreFunctionPrologue(Toks)) {
+    // Consume everything up to (and including) the matching right brace.
+    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
   }
-  // Consume everything up to (and including) the matching right brace.
-  ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
 
   // If we're in a function-try-block, we need to store all the catch blocks.
   if (kind == tok::kw_try) {

Modified: cfe/trunk/test/Parser/cxx-member-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-member-initializers.cpp?rev=140847&r1=140846&r2=140847&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-member-initializers.cpp (original)
+++ cfe/trunk/test/Parser/cxx-member-initializers.cpp Fri Sep 30 03:32:17 2011
@@ -8,3 +8,8 @@
   int a;
   y() : a(4) ; // expected-error {{expected '{'}}
 };
+
+struct z {
+  int a;
+  z() : a {} // expected-error {{expected '('}}
+};

Modified: cfe/trunk/test/Parser/cxx0x-member-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-member-initializers.cpp?rev=140847&r1=140846&r2=140847&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-member-initializers.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-member-initializers.cpp Fri Sep 30 03:32:17 2011
@@ -13,3 +13,17 @@
   int b = 2;
   int c = b; // expected-error {{undeclared identifier}}
 };
+
+// Test recovery for bad constructor initializers
+
+struct R1 {
+  int a;
+  R1() : a {}
+}; // expected-error {{expected '{' or ','}}
+
+// Test correct parsing.
+
+struct V1 {
+  int a, b;
+  V1() : a(), b{} {}
+};





More information about the cfe-commits mailing list