================
@@ -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