cor3ntin updated this revision to Diff 517248.
cor3ntin added a comment.

Fix whitespace only changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149276/new/

https://reviews.llvm.org/D149276

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/Parser/cxx1z-decomposition.cpp
  clang/test/Parser/cxx2b-auto-x.cpp

Index: clang/test/Parser/cxx2b-auto-x.cpp
===================================================================
--- clang/test/Parser/cxx2b-auto-x.cpp
+++ clang/test/Parser/cxx2b-auto-x.cpp
@@ -18,7 +18,25 @@
 
 using T = looks_like_declaration *;
 void f() { T(&a)->n = 1; }
-// FIXME: They should be deemed expressions without breaking function pointer
-//        parameter declarations with trailing return types.
-// void g() { auto(&a)->n = 0; }
-// void h() { auto{&a}->n = 0; }
+void g() { auto(&a)->n = 0; }
+void h() { auto{&a}->n = 0; }
+
+void e(auto (*p)(int y) -> decltype(y)) {}
+
+struct M;
+struct S{
+    S operator()();
+    S* operator->();
+    int N;
+    int M;
+} s; // expected-note {{here}}
+
+void test() {
+    auto(s)()->N; // expected-warning {{expression result unused}}
+    auto(s)()->M; // expected-error {{redefinition of 's' as different kind of symbol}}
+}
+
+void test_paren() {
+    int a = (auto(0));
+    int b = (auto{0});
+}
Index: clang/test/Parser/cxx1z-decomposition.cpp
===================================================================
--- clang/test/Parser/cxx1z-decomposition.cpp
+++ clang/test/Parser/cxx1z-decomposition.cpp
@@ -94,7 +94,9 @@
     // defining-type-specifiers other than cv-qualifiers and 'auto'
     S [a] = s; // expected-error {{cannot be declared with type 'S'}}
     decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}}
-    auto ([c]) = s; // expected-error {{cannot be declared with parentheses}}
+    auto ([c]) = s; // expected-error {{'auto' not allowed here}} \
+                    // expected-error {{use of undeclared identifier 'c'}} \
+                    // expected-error {{expected body of lambda expression}}
 
     // FIXME: This error is not very good.
     auto [d]() = s; // expected-error {{expected ';'}} expected-error {{expected expression}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -840,13 +840,7 @@
       D.hasGroupingParens() || D.getNumTypeObjects() > 1 ||
       (D.getNumTypeObjects() == 1 &&
        D.getTypeObject(0).Kind != DeclaratorChunk::Reference)) {
-    Diag(Decomp.getLSquareLoc(),
-         (D.hasGroupingParens() ||
-          (D.getNumTypeObjects() &&
-           D.getTypeObject(0).Kind == DeclaratorChunk::Paren))
-             ? diag::err_decomp_decl_parens
-             : diag::err_decomp_decl_type)
-        << R;
+    Diag(Decomp.getLSquareLoc(), diag::err_decomp_decl_type) << R;
 
     // In most cases, there's no actual problem with an explicitly-specified
     // type, but a function type won't work here, and ActOnVariableDeclarator
Index: clang/lib/Parse/Parser.cpp
===================================================================
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1950,7 +1950,7 @@
   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
           Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
           Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
-          Tok.is(tok::kw___super)) &&
+          Tok.is(tok::kw___super) || Tok.is(tok::kw_auto)) &&
          "Cannot be a type or scope token!");
 
   if (Tok.is(tok::kw_typename)) {
Index: clang/lib/Parse/ParseTentative.cpp
===================================================================
--- clang/lib/Parse/ParseTentative.cpp
+++ clang/lib/Parse/ParseTentative.cpp
@@ -234,7 +234,7 @@
       return TPResult::Error;
     if (Tok.is(tok::annot_cxxscope))
       ConsumeAnnotationToken();
-    if (Tok.is(tok::identifier))
+    if (Tok.isOneOf(tok::identifier, tok::kw_auto))
       ConsumeToken();
     else if (Tok.is(tok::annot_template_id))
       ConsumeAnnotationToken();
@@ -265,6 +265,7 @@
 ///    attribute-specifier-seqopt type-specifier-seq declarator
 ///
 Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
+  bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
   if (TryConsumeDeclarationSpecifier() == TPResult::Error)
     return TPResult::Error;
 
@@ -280,7 +281,8 @@
     assert(TPR == TPResult::False);
   }
 
-  TPResult TPR = TryParseInitDeclaratorList();
+  TPResult TPR = TryParseInitDeclaratorList(
+      /*mayHaveTrailingReturnType=*/DeclSpecifierIsAuto);
   if (TPR != TPResult::Ambiguous)
     return TPR;
 
@@ -317,10 +319,15 @@
 ///         '{' initializer-list ','[opt] '}'
 ///         '{' '}'
 ///
-Parser::TPResult Parser::TryParseInitDeclaratorList() {
+Parser::TPResult
+Parser::TryParseInitDeclaratorList(bool mayHaveTrailingReturnType) {
   while (true) {
     // declarator
-    TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
+    TPResult TPR = TryParseDeclarator(
+        /*mayBeAbstract=*/false,
+        /*mayHaveIdentifier=*/true,
+        /*mayHaveDirectInit=*/false,
+        /*mayHaveTrailingReturnType=*/mayHaveTrailingReturnType);
     if (TPR != TPResult::Ambiguous)
       return TPR;
 
@@ -535,13 +542,18 @@
   RevertingTentativeParsingAction PA(*this);
 
   // FIXME: A tag definition unambiguously tells us this is an init-statement.
+  bool mayHaveTrailingReturnType = Tok.is(tok::kw_auto);
   if (State.update(TryConsumeDeclarationSpecifier()))
     return State.result();
   assert(Tok.is(tok::l_paren) && "Expected '('");
 
   while (true) {
     // Consume a declarator.
-    if (State.update(TryParseDeclarator(false/*mayBeAbstract*/)))
+    if (State.update(TryParseDeclarator(
+            /*mayBeAbstract=*/false,
+            /*mayHaveIdentifier=*/true,
+            /*mayHaveDirectInit=*/false,
+            /*mayHaveTrailingReturnType=*/mayHaveTrailingReturnType)))
       return State.result();
 
     // Attributes, asm label, or an initializer imply this is not an expression.
@@ -626,13 +638,16 @@
   // We need tentative parsing...
 
   RevertingTentativeParsingAction PA(*this);
+  bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
 
   // type-specifier-seq
   TryConsumeDeclarationSpecifier();
   assert(Tok.is(tok::l_paren) && "Expected '('");
 
   // declarator
-  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
+  TPR = TryParseDeclarator(true /*mayBeAbstract*/, false /*mayHaveIdentifier*/,
+                           /*mayHaveDirectInit=*/false,
+                           MayHaveTrailingReturnType);
 
   // In case of an error, let the declaration parsing code handle it.
   if (TPR == TPResult::Error)
@@ -661,6 +676,9 @@
       TPR = TPResult::True;
       isAmbiguous = true;
 
+    } else if (Context == TypeIdInTrailingReturnType) {
+      TPR = TPResult::True;
+      isAmbiguous = true;
     } else
       TPR = TPResult::False;
   }
@@ -1045,7 +1063,8 @@
 ///
 Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
                                             bool mayHaveIdentifier,
-                                            bool mayHaveDirectInit) {
+                                            bool mayHaveDirectInit,
+                                            bool mayHaveTrailingReturnType) {
   // declarator:
   //   direct-declarator
   //   ptr-operator declarator
@@ -1087,7 +1106,7 @@
              ImplicitTypenameContext::No))) { // 'int(int)' is a function.
       // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
       //        exception-specification[opt]
-      TPResult TPR = TryParseFunctionDeclarator();
+      TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
       if (TPR != TPResult::Ambiguous)
         return TPR;
     } else {
@@ -1126,7 +1145,7 @@
       // direct-declarator '(' parameter-declaration-clause ')'
       //        cv-qualifier-seq[opt] exception-specification[opt]
       ConsumeParen();
-      TPR = TryParseFunctionDeclarator();
+      TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
     } else if (Tok.is(tok::l_square)) {
       // direct-declarator '[' constant-expression[opt] ']'
       // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
@@ -1393,6 +1412,15 @@
     return isCXXDeclarationSpecifier(ImplicitTypenameContext::Yes,
                                      BracedCastResult, InvalidAsDeclSpec);
 
+  case tok::kw_auto: {
+    if (NextToken().is(tok::l_brace))
+      return TPResult::False;
+    if (NextToken().is(tok::l_paren)) {
+      return TPResult::Ambiguous;
+    }
+    return TPResult::True;
+  }
+
   case tok::coloncolon: {    // ::foo::bar
     const Token &Next = NextToken();
     if (Next.isOneOf(tok::kw_new,       // ::new
@@ -1426,7 +1454,6 @@
   case tok::kw_static:
   case tok::kw_extern:
   case tok::kw_mutable:
-  case tok::kw_auto:
   case tok::kw___thread:
   case tok::kw_thread_local:
   case tok::kw__Thread_local:
@@ -2026,7 +2053,10 @@
 
     // declarator
     // abstract-declarator[opt]
-    TPR = TryParseDeclarator(true/*mayBeAbstract*/);
+    TPR = TryParseDeclarator(/*mayBeAbstract=*/true,
+                             /*mayHaveIdentifier=*/true,
+                             /*mayHaveDirectInit=*/false,
+                             /*mayHaveTrailingReturnType=*/true);
     if (TPR != TPResult::Ambiguous)
       return TPR;
 
@@ -2080,7 +2110,8 @@
 /// exception-specification:
 ///   'throw' '(' type-id-list[opt] ')'
 ///
-Parser::TPResult Parser::TryParseFunctionDeclarator() {
+Parser::TPResult
+Parser::TryParseFunctionDeclarator(bool mayHaveTrailingReturnType) {
   // The '(' is already parsed.
 
   TPResult TPR = TryParseParameterDeclarationClause();
@@ -2125,6 +2156,19 @@
     }
   }
 
+  // attribute-specifier-seq
+  if (!TrySkipAttributes())
+    return TPResult::Ambiguous;
+
+  // trailing-return-type
+  if (Tok.is(tok::arrow) && mayHaveTrailingReturnType) {
+    if (TPR == TPResult::True)
+      return TPR;
+    ConsumeToken();
+    if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
+      return TPResult::True;
+  }
+
   return TPResult::Ambiguous;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6491,8 +6491,9 @@
     // that it's an initializer instead.
     if (D.mayOmitIdentifier() && D.mayBeFollowedByCXXDirectInit()) {
       RevertingTentativeParsingAction PA(*this);
-      if (TryParseDeclarator(true, D.mayHaveIdentifier(), true) ==
-              TPResult::False) {
+      if (TryParseDeclarator(true, D.mayHaveIdentifier(), true,
+                             D.getDeclSpec().getTypeSpecType() == TST_auto) ==
+          TPResult::False) {
         D.SetIdentifier(nullptr, Tok.getLocation());
         goto PastIdentifier;
       }
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2521,10 +2521,10 @@
   enum TentativeCXXTypeIdContext {
     TypeIdInParens,
     TypeIdUnambiguous,
-    TypeIdAsTemplateArgument
+    TypeIdAsTemplateArgument,
+    TypeIdInTrailingReturnType,
   };
 
-
   /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
   /// whether the parens contain an expression or a type-id.
   /// Returns true for a type-id and false for an expression.
@@ -2652,14 +2652,15 @@
   TPResult TryParseProtocolQualifiers();
   TPResult TryParsePtrOperatorSeq();
   TPResult TryParseOperatorId();
-  TPResult TryParseInitDeclaratorList();
+  TPResult TryParseInitDeclaratorList(bool mayHaveTrailingReturnType = false);
   TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
-                              bool mayHaveDirectInit = false);
+                              bool mayHaveDirectInit = false,
+                              bool mayHaveTrailingReturnType = false);
   TPResult TryParseParameterDeclarationClause(
       bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false,
       ImplicitTypenameContext AllowImplicitTypename =
           ImplicitTypenameContext::No);
-  TPResult TryParseFunctionDeclarator();
+  TPResult TryParseFunctionDeclarator(bool mayHaveTrailingReturnType = false);
   TPResult TryParseBracketDeclarator();
   TPResult TryConsumeDeclarationSpecifier();
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -496,8 +496,6 @@
   "declared type must be 'auto' or reference to 'auto'">;
 def err_decomp_decl_constraint : Error<
   "decomposition declaration cannot be declared with constrained 'auto'">;
-def err_decomp_decl_parens : Error<
-  "decomposition declaration cannot be declared with parentheses">;
 def err_decomp_decl_template : Error<
   "decomposition declaration template not supported">;
 def err_decomp_decl_not_alone : Error<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -357,6 +357,7 @@
 - Fix bug in the computation of the ``__has_unique_object_representations``
   builtin for types with unnamed bitfields.
   (`#61336 <https://github.com/llvm/llvm-project/issues/61336>`_)
+- Fix parsing of `auto(x)`, when it is surrounded by parenthesese.
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to