Hi rsmith,

See reddit post for some additional context: 
http://www.reddit.com/r/cpp/comments/2nkcvi/generic_lambda_inconsistency/

An ellipsis following an auto should always be parsed as a parameter pack, not 
as a c-variadic.
  [](auto ...) { }();  // OK.

http://reviews.llvm.org/D6520

Files:
  lib/Parse/ParseDecl.cpp
  test/SemaCXX/cxx1y-generic-lambdas.cpp
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -4873,19 +4873,43 @@
     }
 
     // C++0x [dcl.fct]p14:
-    //   There is a syntactic ambiguity when an ellipsis occurs at the end
-    //   of a parameter-declaration-clause without a preceding comma. In
-    //   this case, the ellipsis is parsed as part of the
-    //   abstract-declarator if the type of the parameter names a template
-    //   parameter pack that has not been expanded; otherwise, it is parsed
-    //   as part of the parameter-declaration-clause.
-    if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
-        !((D.getContext() == Declarator::PrototypeContext ||
-           D.getContext() == Declarator::LambdaExprParameterContext ||
-           D.getContext() == Declarator::BlockLiteralContext) &&
-          NextToken().is(tok::r_paren) &&
-          !D.hasGroupingParens() &&
-          !Actions.containsUnexpandedParameterPacks(D))) {
+    //   There is a syntactic ambiguity when an ellipsis occurs at the end of a
+    //   parameter-declaration-clause without a preceding comma. In this case,
+    //   the ellipsis is parsed as part of the abstract-declarator if the type
+    //   of the parameter either names a template parameter pack that has not
+    //   been expanded or contains auto; otherwise, it is parsed as part of the
+    //   parameter-declaration-clause.
+    auto IsEllipsisThatShouldBeParsedAsAbstractDeclarator =
+        [this](const Token &CurTok, Declarator &D) {
+      if (!CurTok.is(tok::ellipsis))
+        return false;
+      // Any scope specifier prevents integrating the ellipsis into the
+      // Declarator.
+      if (!D.getCXXScopeSpec().isEmpty())
+        return false;
+      
+      const Declarator::TheContext DCtx = D.getContext();
+      const bool IsParameterDeclarationContext =
+          DCtx == Declarator::PrototypeContext ||
+          DCtx == Declarator::LambdaExprParameterContext ||
+          DCtx == Declarator::BlockLiteralContext;
+
+      // If not in a parameter declaration context; it's a parameter pack.
+      if (!IsParameterDeclarationContext)
+        return true;
+      // Or if the next token is not a right paren; it's a parameter pack.
+      if (!this->NextToken().is(tok::r_paren))
+        return true;
+      // Or if the decl-specifier is 'auto'; it's a parameter pack.
+      if (D.getDeclSpec().getTypeSpecType() == TST_auto)
+        return true;
+      // Or if there are grouping parens; it's a parameter pack.
+      if (D.hasGroupingParens())
+        return true;
+      // Or if the declarator contains an unexpanded parameter pack
+      return this->Actions.containsUnexpandedParameterPacks(D);
+    };
+    if (IsEllipsisThatShouldBeParsedAsAbstractDeclarator(Tok, D)) {
       SourceLocation EllipsisLoc = ConsumeToken();
       if (isPtrOperatorToken(Tok.getKind(), getLangOpts(), D.getContext())) {
         // The ellipsis was put in the wrong place. Recover, and explain to
Index: test/SemaCXX/cxx1y-generic-lambdas.cpp
===================================================================
--- test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -918,3 +918,7 @@
 
 
 } //end ns inclass_lambdas_within_nested_classes
+
+namespace pr21684_disambiguate_auto_followed_by_ellipsis_no_id {
+int a = [](auto ...) { return 0; }();
+}
\ No newline at end of file
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to