================
@@ -3860,6 +3875,44 @@ void Parser::ParseDeclarationSpecifiers(
         goto DoneWithDeclSpec;
       }
 
+      // If 'auto' is set and this identifier is a type name, check if it's
+      // followed by declarator tokens (like '=', '(', '[', etc.). If so, this
+      // identifier is likely the variable name, not a type specifier, so we
+      // should stop parsing declaration specifiers.
+      // Also check for concept constraint syntax (C<T> auto param) where
+      // the identifier before 'auto' might be a concept, not a type conflict.
+      // Also check for template parameters (template<auto V>) and lambda
+      // parameters
+      // ([](auto c)) where the identifier is a parameter name, not a type
+      // conflict.
+      if (DS.getTypeSpecType() == DeclSpec::TST_auto && TypeRep) {
+        // Check if the next token indicates this is a declarator
+        Token Next = NextToken();
+        if (Next.isOneOf(tok::equal, tok::l_paren, tok::l_square, tok::amp,
+                         tok::ampamp, tok::star, tok::coloncolon, tok::comma,
+                         tok::semi, tok::colon, tok::greater, tok::r_paren,
+                         tok::arrow)) {
+          // This identifier is likely the variable/parameter name, stop 
parsing
+          // decl specifiers. Note: ':' is for range-based for loops:
+          // for (auto Arg: x).
+          // Note: '>' is for template parameters: template<auto V>
+          // Note: ')' is for function/lambda parameters: [](auto c)
+          // Note: '->' is for lambda return types: [](auto c) -> int
+          goto DoneWithDeclSpec;
+        }
+        // Check for concept constraint syntax: C<T> auto param)
+        // If the identifier is followed by 'auto' and then an identifier 
that's
+        // followed by ')', this might be concept syntax, not a type conflict.
+        if (Next.is(tok::identifier)) {
+          // Look ahead to see if this is followed by ')' (function parameter)
+          Token AfterNext = GetLookAheadToken(2);
+          if (AfterNext.is(tok::r_paren)) {
+            // This might be concept constraint syntax, skip conflict detection
+            goto DoneWithDeclSpec;
+          }
+        }
+      }
+
----------------
osamakader wrote:

I moved the auto conflict handling/diagnostic into DeclSpec::Finish() in Sema. 
I think this remaining part needs to stay in the parser because it decides 
where declaration-specifiers end before consuming the identifier. Once the 
parser consumes a typedef-name-looking identifier as a type specifier, Sema can 
diagnose the conflict but cannot recover the intended declarator-id parse for 
cases like [](auto c), template<auto V>, or for (auto Arg : range).

https://github.com/llvm/llvm-project/pull/166004
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to