clang 20.0.0git
ParseTentative.cpp
Go to the documentation of this file.
1//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the tentative parsing portions of the Parser
10// interfaces, for ambiguity resolution.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
17using namespace clang;
18
19/// isCXXDeclarationStatement - C++-specialized function that disambiguates
20/// between a declaration or an expression statement, when parsing function
21/// bodies. Returns true for declaration, false for expression.
22///
23/// declaration-statement:
24/// block-declaration
25///
26/// block-declaration:
27/// simple-declaration
28/// asm-definition
29/// namespace-alias-definition
30/// using-declaration
31/// using-directive
32/// [C++0x] static_assert-declaration
33///
34/// asm-definition:
35/// 'asm' '(' string-literal ')' ';'
36///
37/// namespace-alias-definition:
38/// 'namespace' identifier = qualified-namespace-specifier ';'
39///
40/// using-declaration:
41/// 'using' typename[opt] '::'[opt] nested-name-specifier
42/// unqualified-id ';'
43/// 'using' '::' unqualified-id ;
44///
45/// using-directive:
46/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt]
47/// namespace-name ';'
48///
49bool Parser::isCXXDeclarationStatement(
50 bool DisambiguatingWithExpression /*=false*/) {
51 assert(getLangOpts().CPlusPlus && "Must be called for C++ only.");
52
53 switch (Tok.getKind()) {
54 // asm-definition
55 case tok::kw_asm:
56 // namespace-alias-definition
57 case tok::kw_namespace:
58 // using-declaration
59 // using-directive
60 case tok::kw_using:
61 // static_assert-declaration
62 case tok::kw_static_assert:
63 case tok::kw__Static_assert:
64 return true;
65 case tok::coloncolon:
66 case tok::identifier: {
67 if (DisambiguatingWithExpression) {
68 RevertingTentativeParsingAction TPA(*this);
69 // Parse the C++ scope specifier.
70 CXXScopeSpec SS;
71 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
72 /*ObjectHasErrors=*/false,
73 /*EnteringContext=*/true);
74
75 switch (Tok.getKind()) {
76 case tok::identifier: {
78 bool isDeductionGuide = Actions.isDeductionGuideName(
79 getCurScope(), *II, Tok.getLocation(), SS, /*Template=*/nullptr);
80 if (Actions.isCurrentClassName(*II, getCurScope(), &SS) ||
81 isDeductionGuide) {
82 if (isConstructorDeclarator(
83 /*Unqualified=*/SS.isEmpty(), isDeductionGuide,
85 return true;
86 } else if (SS.isNotEmpty()) {
87 // If the scope is not empty, it could alternatively be something like
88 // a typedef or using declaration. That declaration might be private
89 // in the global context, which would be diagnosed by calling into
90 // isCXXSimpleDeclaration, but may actually be fine in the context of
91 // member functions and static variable definitions. Check if the next
92 // token is also an identifier and assume a declaration.
93 // We cannot check if the scopes match because the declarations could
94 // involve namespaces and friend declarations.
95 if (NextToken().is(tok::identifier))
96 return true;
97 }
98 break;
99 }
100 case tok::kw_operator:
101 return true;
102 case tok::tilde:
103 return true;
104 default:
105 break;
106 }
107 }
108 }
109 [[fallthrough]];
110 // simple-declaration
111 default:
112 return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
113 }
114}
115
116/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
117/// between a simple-declaration or an expression-statement.
118/// If during the disambiguation process a parsing error is encountered,
119/// the function returns true to let the declaration parsing code handle it.
120/// Returns false if the statement is disambiguated as expression.
121///
122/// simple-declaration:
123/// decl-specifier-seq init-declarator-list[opt] ';'
124/// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
125/// brace-or-equal-initializer ';' [C++17]
126///
127/// (if AllowForRangeDecl specified)
128/// for ( for-range-declaration : for-range-initializer ) statement
129///
130/// for-range-declaration:
131/// decl-specifier-seq declarator
132/// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
133///
134/// In any of the above cases there can be a preceding attribute-specifier-seq,
135/// but the caller is expected to handle that.
136bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
137 // C++ 6.8p1:
138 // There is an ambiguity in the grammar involving expression-statements and
139 // declarations: An expression-statement with a function-style explicit type
140 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
141 // from a declaration where the first declarator starts with a '('. In those
142 // cases the statement is a declaration. [Note: To disambiguate, the whole
143 // statement might have to be examined to determine if it is an
144 // expression-statement or a declaration].
145
146 // C++ 6.8p3:
147 // The disambiguation is purely syntactic; that is, the meaning of the names
148 // occurring in such a statement, beyond whether they are type-names or not,
149 // is not generally used in or changed by the disambiguation. Class
150 // templates are instantiated as necessary to determine if a qualified name
151 // is a type-name. Disambiguation precedes parsing, and a statement
152 // disambiguated as a declaration may be an ill-formed declaration.
153
154 // We don't have to parse all of the decl-specifier-seq part. There's only
155 // an ambiguity if the first decl-specifier is
156 // simple-type-specifier/typename-specifier followed by a '(', which may
157 // indicate a function-style cast expression.
158 // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such
159 // a case.
160
161 bool InvalidAsDeclaration = false;
162 TPResult TPR = isCXXDeclarationSpecifier(
163 ImplicitTypenameContext::No, TPResult::False, &InvalidAsDeclaration);
164 if (TPR != TPResult::Ambiguous)
165 return TPR != TPResult::False; // Returns true for TPResult::True or
166 // TPResult::Error.
167
168 // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
169 // and so gets some cases wrong. We can't carry on if we've already seen
170 // something which makes this statement invalid as a declaration in this case,
171 // since it can cause us to misparse valid code. Revisit this once
172 // TryParseInitDeclaratorList is fixed.
173 if (InvalidAsDeclaration)
174 return false;
175
176 // FIXME: Add statistics about the number of ambiguous statements encountered
177 // and how they were resolved (number of declarations+number of expressions).
178
179 // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
180 // or an identifier which doesn't resolve as anything. We need tentative
181 // parsing...
182
183 {
184 RevertingTentativeParsingAction PA(*this);
185 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
186 }
187
188 // In case of an error, let the declaration parsing code handle it.
189 if (TPR == TPResult::Error)
190 return true;
191
192 // Declarations take precedence over expressions.
193 if (TPR == TPResult::Ambiguous)
194 TPR = TPResult::True;
195
196 assert(TPR == TPResult::True || TPR == TPResult::False);
197 return TPR == TPResult::True;
198}
199
200/// Try to consume a token sequence that we've already identified as
201/// (potentially) starting a decl-specifier.
202Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
203 switch (Tok.getKind()) {
204 case tok::kw__Atomic:
205 if (NextToken().isNot(tok::l_paren)) {
206 ConsumeToken();
207 break;
208 }
209 [[fallthrough]];
210 case tok::kw_typeof:
211 case tok::kw___attribute:
212#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
213#include "clang/Basic/TransformTypeTraits.def"
214 {
215 ConsumeToken();
216 if (Tok.isNot(tok::l_paren))
217 return TPResult::Error;
218 ConsumeParen();
219 if (!SkipUntil(tok::r_paren))
220 return TPResult::Error;
221 break;
222 }
223
224 case tok::kw_class:
225 case tok::kw_struct:
226 case tok::kw_union:
227 case tok::kw___interface:
228 case tok::kw_enum:
229 // elaborated-type-specifier:
230 // class-key attribute-specifier-seq[opt]
231 // nested-name-specifier[opt] identifier
232 // class-key nested-name-specifier[opt] template[opt] simple-template-id
233 // enum nested-name-specifier[opt] identifier
234 //
235 // FIXME: We don't support class-specifiers nor enum-specifiers here.
236 ConsumeToken();
237
238 // Skip attributes.
239 if (!TrySkipAttributes())
240 return TPResult::Error;
241
243 return TPResult::Error;
244 if (Tok.is(tok::annot_cxxscope))
245 ConsumeAnnotationToken();
246 if (Tok.is(tok::identifier))
247 ConsumeToken();
248 else if (Tok.is(tok::annot_template_id))
249 ConsumeAnnotationToken();
250 else
251 return TPResult::Error;
252 break;
253
254 case tok::annot_cxxscope:
255 ConsumeAnnotationToken();
256 [[fallthrough]];
257 default:
259
260 if (getLangOpts().ObjC && Tok.is(tok::less))
261 return TryParseProtocolQualifiers();
262 break;
263 }
264
265 return TPResult::Ambiguous;
266}
267
268/// simple-declaration:
269/// decl-specifier-seq init-declarator-list[opt] ';'
270///
271/// (if AllowForRangeDecl specified)
272/// for ( for-range-declaration : for-range-initializer ) statement
273/// for-range-declaration:
274/// attribute-specifier-seqopt type-specifier-seq declarator
275///
276Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
277 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
278 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
279 return TPResult::Error;
280
281 // Two decl-specifiers in a row conclusively disambiguate this as being a
282 // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
283 // overwhelmingly common case that the next token is a '('.
284 if (Tok.isNot(tok::l_paren)) {
285 TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
286 if (TPR == TPResult::Ambiguous)
287 return TPResult::True;
288 if (TPR == TPResult::True || TPR == TPResult::Error)
289 return TPR;
290 assert(TPR == TPResult::False);
291 }
292
293 TPResult TPR = TryParseInitDeclaratorList(
294 /*mayHaveTrailingReturnType=*/DeclSpecifierIsAuto);
295 if (TPR != TPResult::Ambiguous)
296 return TPR;
297
298 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
299 return TPResult::False;
300
301 return TPResult::Ambiguous;
302}
303
304/// Tentatively parse an init-declarator-list in order to disambiguate it from
305/// an expression.
306///
307/// init-declarator-list:
308/// init-declarator
309/// init-declarator-list ',' init-declarator
310///
311/// init-declarator:
312/// declarator initializer[opt]
313/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
314///
315/// initializer:
316/// brace-or-equal-initializer
317/// '(' expression-list ')'
318///
319/// brace-or-equal-initializer:
320/// '=' initializer-clause
321/// [C++11] braced-init-list
322///
323/// initializer-clause:
324/// assignment-expression
325/// braced-init-list
326///
327/// braced-init-list:
328/// '{' initializer-list ','[opt] '}'
329/// '{' '}'
330///
331Parser::TPResult
332Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {
333 while (true) {
334 // declarator
335 TPResult TPR = TryParseDeclarator(
336 /*mayBeAbstract=*/false,
337 /*mayHaveIdentifier=*/true,
338 /*mayHaveDirectInit=*/false,
339 /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType);
340 if (TPR != TPResult::Ambiguous)
341 return TPR;
342
343 // [GNU] simple-asm-expr[opt] attributes[opt]
344 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
345 return TPResult::True;
346
347 // initializer[opt]
348 if (Tok.is(tok::l_paren)) {
349 // Parse through the parens.
350 ConsumeParen();
351 if (!SkipUntil(tok::r_paren, StopAtSemi))
352 return TPResult::Error;
353 } else if (Tok.is(tok::l_brace)) {
354 // A left-brace here is sufficient to disambiguate the parse; an
355 // expression can never be followed directly by a braced-init-list.
356 return TPResult::True;
357 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
358 // MSVC and g++ won't examine the rest of declarators if '=' is
359 // encountered; they just conclude that we have a declaration.
360 // EDG parses the initializer completely, which is the proper behavior
361 // for this case.
362 //
363 // At present, Clang follows MSVC and g++, since the parser does not have
364 // the ability to parse an expression fully without recording the
365 // results of that parse.
366 // FIXME: Handle this case correctly.
367 //
368 // Also allow 'in' after an Objective-C declaration as in:
369 // for (int (^b)(void) in array). Ideally this should be done in the
370 // context of parsing for-init-statement of a foreach statement only. But,
371 // in any other context 'in' is invalid after a declaration and parser
372 // issues the error regardless of outcome of this decision.
373 // FIXME: Change if above assumption does not hold.
374 return TPResult::True;
375 }
376
377 if (!TryConsumeToken(tok::comma))
378 break;
379 }
380
381 return TPResult::Ambiguous;
382}
383
386 bool CanBeExpression = true;
387 bool CanBeCondition = true;
390
395
396 bool resolved() {
399 }
400
402 CanBeExpression = false;
403
404 if (!resolved()) {
405 // FIXME: Unify the parsing codepaths for condition variables and
406 // simple-declarations so that we don't need to eagerly figure out which
407 // kind we have here. (Just parse init-declarators until we reach a
408 // semicolon or right paren.)
409 RevertingTentativeParsingAction PA(P);
410 if (CanBeForRangeDecl) {
411 // Skip until we hit a ')', ';', or a ':' with no matching '?'.
412 // The final case is a for range declaration, the rest are not.
413 unsigned QuestionColonDepth = 0;
414 while (true) {
415 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
417 if (P.Tok.is(tok::question))
418 ++QuestionColonDepth;
419 else if (P.Tok.is(tok::colon)) {
420 if (QuestionColonDepth)
421 --QuestionColonDepth;
422 else {
424 return;
425 }
426 } else {
427 CanBeForRangeDecl = false;
428 break;
429 }
430 P.ConsumeToken();
431 }
432 } else {
433 // Just skip until we hit a ')' or ';'.
434 P.SkipUntil(tok::r_paren, tok::semi, StopBeforeMatch);
435 }
436 if (P.Tok.isNot(tok::r_paren))
438 if (P.Tok.isNot(tok::semi))
439 CanBeInitStatement = false;
440 }
441 }
442
444 CanBeCondition = false;
445 return resolved();
446 }
447
449 CanBeForRangeDecl = false;
450 return resolved();
451 }
452
453 bool update(TPResult IsDecl) {
454 switch (IsDecl) {
455 case TPResult::True:
457 assert(resolved() && "can't continue after tentative parsing bails out");
458 break;
459 case TPResult::False:
461 break;
462 case TPResult::Ambiguous:
463 break;
464 case TPResult::Error:
466 CanBeForRangeDecl = false;
467 break;
468 }
469 return resolved();
470 }
471
472 ConditionOrInitStatement result() const {
474 CanBeForRangeDecl < 2 &&
475 "result called but not yet resolved");
476 if (CanBeExpression)
477 return ConditionOrInitStatement::Expression;
478 if (CanBeCondition)
479 return ConditionOrInitStatement::ConditionDecl;
481 return ConditionOrInitStatement::InitStmtDecl;
483 return ConditionOrInitStatement::ForRangeDecl;
484 return ConditionOrInitStatement::Error;
485 }
486};
487
488bool Parser::isEnumBase(bool AllowSemi) {
489 assert(Tok.is(tok::colon) && "should be looking at the ':'");
490
491 RevertingTentativeParsingAction PA(*this);
492 // ':'
493 ConsumeToken();
494
495 // type-specifier-seq
496 bool InvalidAsDeclSpec = false;
497 // FIXME: We could disallow non-type decl-specifiers here, but it makes no
498 // difference: those specifiers are ill-formed regardless of the
499 // interpretation.
500 TPResult R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No,
501 /*BracedCastResult=*/TPResult::True,
502 &InvalidAsDeclSpec);
503 if (R == TPResult::Ambiguous) {
504 // We either have a decl-specifier followed by '(' or an undeclared
505 // identifier.
506 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
507 return true;
508
509 // If we get to the end of the enum-base, we hit either a '{' or a ';'.
510 // Don't bother checking the enumerator-list.
511 if (Tok.is(tok::l_brace) || (AllowSemi && Tok.is(tok::semi)))
512 return true;
513
514 // A second decl-specifier unambiguously indicatges an enum-base.
515 R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::True,
516 &InvalidAsDeclSpec);
517 }
518
519 return R != TPResult::False;
520}
521
522/// Disambiguates between a declaration in a condition, a
523/// simple-declaration in an init-statement, and an expression for
524/// a condition of a if/switch statement.
525///
526/// condition:
527/// expression
528/// type-specifier-seq declarator '=' assignment-expression
529/// [C++11] type-specifier-seq declarator '=' initializer-clause
530/// [C++11] type-specifier-seq declarator braced-init-list
531/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
532/// '=' assignment-expression
533/// simple-declaration:
534/// decl-specifier-seq init-declarator-list[opt] ';'
535///
536/// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way
537/// to the ';' to disambiguate cases like 'int(x))' (an expression) from
538/// 'int(x);' (a simple-declaration in an init-statement).
539Parser::ConditionOrInitStatement
540Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
541 bool CanBeForRangeDecl) {
542 ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,
543 CanBeForRangeDecl);
544
545 if (CanBeInitStatement && Tok.is(tok::kw_using))
546 return ConditionOrInitStatement::InitStmtDecl;
547 if (State.update(isCXXDeclarationSpecifier(ImplicitTypenameContext::No)))
548 return State.result();
549
550 // It might be a declaration; we need tentative parsing.
551 RevertingTentativeParsingAction PA(*this);
552
553 // FIXME: A tag definition unambiguously tells us this is an init-statement.
554 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
555 if (State.update(TryConsumeDeclarationSpecifier()))
556 return State.result();
557 assert(Tok.is(tok::l_paren) && "Expected '('");
558
559 while (true) {
560 // Consume a declarator.
561 if (State.update(TryParseDeclarator(
562 /*mayBeAbstract=*/false,
563 /*mayHaveIdentifier=*/true,
564 /*mayHaveDirectInit=*/false,
565 /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType)))
566 return State.result();
567
568 // Attributes, asm label, or an initializer imply this is not an expression.
569 // FIXME: Disambiguate properly after an = instead of assuming that it's a
570 // valid declaration.
571 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
572 (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) {
573 State.markNotExpression();
574 return State.result();
575 }
576
577 // A colon here identifies a for-range declaration.
578 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
579 return ConditionOrInitStatement::ForRangeDecl;
580
581 // At this point, it can't be a condition any more, because a condition
582 // must have a brace-or-equal-initializer.
583 if (State.markNotCondition())
584 return State.result();
585
586 // Likewise, it can't be a for-range declaration any more.
587 if (State.markNotForRangeDecl())
588 return State.result();
589
590 // A parenthesized initializer could be part of an expression or a
591 // simple-declaration.
592 if (Tok.is(tok::l_paren)) {
593 ConsumeParen();
594 SkipUntil(tok::r_paren, StopAtSemi);
595 }
596
597 if (!TryConsumeToken(tok::comma))
598 break;
599 }
600
601 // We reached the end. If it can now be some kind of decl, then it is.
602 if (State.CanBeCondition && Tok.is(tok::r_paren))
603 return ConditionOrInitStatement::ConditionDecl;
604 else if (State.CanBeInitStatement && Tok.is(tok::semi))
605 return ConditionOrInitStatement::InitStmtDecl;
606 else
607 return ConditionOrInitStatement::Expression;
608}
609
610 /// Determine whether the next set of tokens contains a type-id.
611 ///
612 /// The context parameter states what context we're parsing right
613 /// now, which affects how this routine copes with the token
614 /// following the type-id. If the context is TypeIdInParens, we have
615 /// already parsed the '(' and we will cease lookahead when we hit
616 /// the corresponding ')'. If the context is
617 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
618 /// before this template argument, and will cease lookahead when we
619 /// hit a '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
620 /// preceding such. Returns true for a type-id and false for an expression.
621 /// If during the disambiguation process a parsing error is encountered,
622 /// the function returns true to let the declaration parsing code handle it.
623 ///
624 /// type-id:
625 /// type-specifier-seq abstract-declarator[opt]
626 ///
627bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
628
629 isAmbiguous = false;
630
631 // C++ 8.2p2:
632 // The ambiguity arising from the similarity between a function-style cast and
633 // a type-id can occur in different contexts. The ambiguity appears as a
634 // choice between a function-style cast expression and a declaration of a
635 // type. The resolution is that any construct that could possibly be a type-id
636 // in its syntactic context shall be considered a type-id.
637
638 TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
639 if (TPR != TPResult::Ambiguous)
640 return TPR != TPResult::False; // Returns true for TPResult::True or
641 // TPResult::Error.
642
643 // FIXME: Add statistics about the number of ambiguous statements encountered
644 // and how they were resolved (number of declarations+number of expressions).
645
646 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
647 // We need tentative parsing...
648
649 RevertingTentativeParsingAction PA(*this);
650 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
651
652 // type-specifier-seq
653 TryConsumeDeclarationSpecifier();
654 assert(Tok.is(tok::l_paren) && "Expected '('");
655
656 // declarator
657 TPR = TryParseDeclarator(true /*mayBeAbstract*/, false /*mayHaveIdentifier*/,
658 /*mayHaveDirectInit=*/false,
659 MayHaveTrailingReturnType);
660
661 // In case of an error, let the declaration parsing code handle it.
662 if (TPR == TPResult::Error)
663 TPR = TPResult::True;
664
665 if (TPR == TPResult::Ambiguous) {
666 // We are supposed to be inside parens, so if after the abstract declarator
667 // we encounter a ')' this is a type-id, otherwise it's an expression.
668 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
669 TPR = TPResult::True;
670 isAmbiguous = true;
671 // We are supposed to be inside the first operand to a _Generic selection
672 // expression, so if we find a comma after the declarator, we've found a
673 // type and not an expression.
674 } else if (Context == TypeIdAsGenericSelectionArgument && Tok.is(tok::comma)) {
675 TPR = TPResult::True;
676 isAmbiguous = true;
677 // We are supposed to be inside a template argument, so if after
678 // the abstract declarator we encounter a '>', '>>' (in C++0x), or
679 // ','; or, in C++0x, an ellipsis immediately preceding such, this
680 // is a type-id. Otherwise, it's an expression.
681 } else if (Context == TypeIdAsTemplateArgument &&
682 (Tok.isOneOf(tok::greater, tok::comma) ||
684 (Tok.isOneOf(tok::greatergreater,
685 tok::greatergreatergreater) ||
686 (Tok.is(tok::ellipsis) &&
687 NextToken().isOneOf(tok::greater, tok::greatergreater,
688 tok::greatergreatergreater,
689 tok::comma)))))) {
690 TPR = TPResult::True;
691 isAmbiguous = true;
692
693 } else if (Context == TypeIdInTrailingReturnType) {
694 TPR = TPResult::True;
695 isAmbiguous = true;
696 } else
697 TPR = TPResult::False;
698 }
699
700 assert(TPR == TPResult::True || TPR == TPResult::False);
701 return TPR == TPResult::True;
702}
703
704/// Returns true if this is a C++11 attribute-specifier. Per
705/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
706/// always introduce an attribute. In Objective-C++11, this rule does not
707/// apply if either '[' begins a message-send.
708///
709/// If Disambiguate is true, we try harder to determine whether a '[[' starts
710/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not.
711///
712/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an
713/// Obj-C message send or the start of an attribute. Otherwise, we assume it
714/// is not an Obj-C message send.
715///
716/// C++11 [dcl.attr.grammar]:
717///
718/// attribute-specifier:
719/// '[' '[' attribute-list ']' ']'
720/// alignment-specifier
721///
722/// attribute-list:
723/// attribute[opt]
724/// attribute-list ',' attribute[opt]
725/// attribute '...'
726/// attribute-list ',' attribute '...'
727///
728/// attribute:
729/// attribute-token attribute-argument-clause[opt]
730///
731/// attribute-token:
732/// identifier
733/// identifier '::' identifier
734///
735/// attribute-argument-clause:
736/// '(' balanced-token-seq ')'
737Parser::CXX11AttributeKind
738Parser::isCXX11AttributeSpecifier(bool Disambiguate,
739 bool OuterMightBeMessageSend) {
740 // alignas is an attribute specifier in C++ but not in C23.
741 if (Tok.is(tok::kw_alignas) && !getLangOpts().C23)
742 return CAK_AttributeSpecifier;
743
745 return CAK_AttributeSpecifier;
746
747 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
748 return CAK_NotAttributeSpecifier;
749
750 // No tentative parsing if we don't need to look for ']]' or a lambda.
751 if (!Disambiguate && !getLangOpts().ObjC)
752 return CAK_AttributeSpecifier;
753
754 // '[[using ns: ...]]' is an attribute.
755 if (GetLookAheadToken(2).is(tok::kw_using))
756 return CAK_AttributeSpecifier;
757
758 RevertingTentativeParsingAction PA(*this);
759
760 // Opening brackets were checked for above.
761 ConsumeBracket();
762
763 if (!getLangOpts().ObjC) {
764 ConsumeBracket();
765
766 bool IsAttribute = SkipUntil(tok::r_square);
767 IsAttribute &= Tok.is(tok::r_square);
768
769 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
770 }
771
772 // In Obj-C++11, we need to distinguish four situations:
773 // 1a) int x[[attr]]; C++11 attribute.
774 // 1b) [[attr]]; C++11 statement attribute.
775 // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index.
776 // 3a) int x[[obj get]]; Message send in array size/index.
777 // 3b) [[Class alloc] init]; Message send in message send.
778 // 4) [[obj]{ return self; }() doStuff]; Lambda in message send.
779 // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.
780
781 // Check to see if this is a lambda-expression.
782 // FIXME: If this disambiguation is too slow, fold the tentative lambda parse
783 // into the tentative attribute parse below.
784 {
785 RevertingTentativeParsingAction LambdaTPA(*this);
786 LambdaIntroducer Intro;
787 LambdaIntroducerTentativeParse Tentative;
788 if (ParseLambdaIntroducer(Intro, &Tentative)) {
789 // We hit a hard error after deciding this was not an attribute.
790 // FIXME: Don't parse and annotate expressions when disambiguating
791 // against an attribute.
792 return CAK_NotAttributeSpecifier;
793 }
794
795 switch (Tentative) {
796 case LambdaIntroducerTentativeParse::MessageSend:
797 // Case 3: The inner construct is definitely a message send, so the
798 // outer construct is definitely not an attribute.
799 return CAK_NotAttributeSpecifier;
800
801 case LambdaIntroducerTentativeParse::Success:
802 case LambdaIntroducerTentativeParse::Incomplete:
803 // This is a lambda-introducer or attribute-specifier.
804 if (Tok.is(tok::r_square))
805 // Case 1: C++11 attribute.
806 return CAK_AttributeSpecifier;
807
808 if (OuterMightBeMessageSend)
809 // Case 4: Lambda in message send.
810 return CAK_NotAttributeSpecifier;
811
812 // Case 2: Lambda in array size / index.
813 return CAK_InvalidAttributeSpecifier;
814
815 case LambdaIntroducerTentativeParse::Invalid:
816 // No idea what this is; we couldn't parse it as a lambda-introducer.
817 // Might still be an attribute-specifier or a message send.
818 break;
819 }
820 }
821
822 ConsumeBracket();
823
824 // If we don't have a lambda-introducer, then we have an attribute or a
825 // message-send.
826 bool IsAttribute = true;
827 while (Tok.isNot(tok::r_square)) {
828 if (Tok.is(tok::comma)) {
829 // Case 1: Stray commas can only occur in attributes.
830 return CAK_AttributeSpecifier;
831 }
832
833 // Parse the attribute-token, if present.
834 // C++11 [dcl.attr.grammar]:
835 // If a keyword or an alternative token that satisfies the syntactic
836 // requirements of an identifier is contained in an attribute-token,
837 // it is considered an identifier.
839 if (!TryParseCXX11AttributeIdentifier(Loc)) {
840 IsAttribute = false;
841 break;
842 }
843 if (Tok.is(tok::coloncolon)) {
844 ConsumeToken();
845 if (!TryParseCXX11AttributeIdentifier(Loc)) {
846 IsAttribute = false;
847 break;
848 }
849 }
850
851 // Parse the attribute-argument-clause, if present.
852 if (Tok.is(tok::l_paren)) {
853 ConsumeParen();
854 if (!SkipUntil(tok::r_paren)) {
855 IsAttribute = false;
856 break;
857 }
858 }
859
860 TryConsumeToken(tok::ellipsis);
861
862 if (!TryConsumeToken(tok::comma))
863 break;
864 }
865
866 // An attribute must end ']]'.
867 if (IsAttribute) {
868 if (Tok.is(tok::r_square)) {
869 ConsumeBracket();
870 IsAttribute = Tok.is(tok::r_square);
871 } else {
872 IsAttribute = false;
873 }
874 }
875
876 if (IsAttribute)
877 // Case 1: C++11 statement attribute.
878 return CAK_AttributeSpecifier;
879
880 // Case 3: Message send.
881 return CAK_NotAttributeSpecifier;
882}
883
884bool Parser::TrySkipAttributes() {
885 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
886 tok::kw_alignas) ||
888 if (Tok.is(tok::l_square)) {
889 ConsumeBracket();
890 if (Tok.isNot(tok::l_square))
891 return false;
892 ConsumeBracket();
893 if (!SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
894 return false;
895 // Note that explicitly checking for `[[` and `]]` allows to fail as
896 // expected in the case of the Objective-C message send syntax.
897 ConsumeBracket();
898 } else if (Tok.isRegularKeywordAttribute() &&
900 ConsumeToken();
901 } else {
902 ConsumeToken();
903 if (Tok.isNot(tok::l_paren))
904 return false;
905 ConsumeParen();
906 if (!SkipUntil(tok::r_paren))
907 return false;
908 }
909 }
910
911 return true;
912}
913
914Parser::TPResult Parser::TryParsePtrOperatorSeq() {
915 while (true) {
917 return TPResult::Error;
918
919 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
920 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
921 // ptr-operator
923
924 // Skip attributes.
925 if (!TrySkipAttributes())
926 return TPResult::Error;
927
928 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
929 tok::kw__Nonnull, tok::kw__Nullable,
930 tok::kw__Nullable_result, tok::kw__Null_unspecified,
931 tok::kw__Atomic))
932 ConsumeToken();
933 } else {
934 return TPResult::True;
935 }
936 }
937}
938
939/// operator-function-id:
940/// 'operator' operator
941///
942/// operator: one of
943/// new delete new[] delete[] + - * / % ^ [...]
944///
945/// conversion-function-id:
946/// 'operator' conversion-type-id
947///
948/// conversion-type-id:
949/// type-specifier-seq conversion-declarator[opt]
950///
951/// conversion-declarator:
952/// ptr-operator conversion-declarator[opt]
953///
954/// literal-operator-id:
955/// 'operator' string-literal identifier
956/// 'operator' user-defined-string-literal
957Parser::TPResult Parser::TryParseOperatorId() {
958 assert(Tok.is(tok::kw_operator));
959 ConsumeToken();
960
961 // Maybe this is an operator-function-id.
962 switch (Tok.getKind()) {
963 case tok::kw_new: case tok::kw_delete:
964 ConsumeToken();
965 if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
966 ConsumeBracket();
967 ConsumeBracket();
968 }
969 return TPResult::True;
970
971#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
972 case tok::Token:
973#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
974#include "clang/Basic/OperatorKinds.def"
975 ConsumeToken();
976 return TPResult::True;
977
978 case tok::l_square:
979 if (NextToken().is(tok::r_square)) {
980 ConsumeBracket();
981 ConsumeBracket();
982 return TPResult::True;
983 }
984 break;
985
986 case tok::l_paren:
987 if (NextToken().is(tok::r_paren)) {
988 ConsumeParen();
989 ConsumeParen();
990 return TPResult::True;
991 }
992 break;
993
994 default:
995 break;
996 }
997
998 // Maybe this is a literal-operator-id.
999 if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
1000 bool FoundUDSuffix = false;
1001 do {
1002 FoundUDSuffix |= Tok.hasUDSuffix();
1003 ConsumeStringToken();
1004 } while (isTokenStringLiteral());
1005
1006 if (!FoundUDSuffix) {
1007 if (Tok.is(tok::identifier))
1008 ConsumeToken();
1009 else
1010 return TPResult::Error;
1011 }
1012 return TPResult::True;
1013 }
1014
1015 // Maybe this is a conversion-function-id.
1016 bool AnyDeclSpecifiers = false;
1017 while (true) {
1018 TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
1019 if (TPR == TPResult::Error)
1020 return TPR;
1021 if (TPR == TPResult::False) {
1022 if (!AnyDeclSpecifiers)
1023 return TPResult::Error;
1024 break;
1025 }
1026 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1027 return TPResult::Error;
1028 AnyDeclSpecifiers = true;
1029 }
1030 return TryParsePtrOperatorSeq();
1031}
1032
1033/// declarator:
1034/// direct-declarator
1035/// ptr-operator declarator
1036///
1037/// direct-declarator:
1038/// declarator-id
1039/// direct-declarator '(' parameter-declaration-clause ')'
1040/// cv-qualifier-seq[opt] exception-specification[opt]
1041/// direct-declarator '[' constant-expression[opt] ']'
1042/// '(' declarator ')'
1043/// [GNU] '(' attributes declarator ')'
1044///
1045/// abstract-declarator:
1046/// ptr-operator abstract-declarator[opt]
1047/// direct-abstract-declarator
1048///
1049/// direct-abstract-declarator:
1050/// direct-abstract-declarator[opt]
1051/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1052/// exception-specification[opt]
1053/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
1054/// '(' abstract-declarator ')'
1055/// [C++0x] ...
1056///
1057/// ptr-operator:
1058/// '*' cv-qualifier-seq[opt]
1059/// '&'
1060/// [C++0x] '&&' [TODO]
1061/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
1062///
1063/// cv-qualifier-seq:
1064/// cv-qualifier cv-qualifier-seq[opt]
1065///
1066/// cv-qualifier:
1067/// 'const'
1068/// 'volatile'
1069///
1070/// declarator-id:
1071/// '...'[opt] id-expression
1072///
1073/// id-expression:
1074/// unqualified-id
1075/// qualified-id [TODO]
1076///
1077/// unqualified-id:
1078/// identifier
1079/// operator-function-id
1080/// conversion-function-id
1081/// literal-operator-id
1082/// '~' class-name [TODO]
1083/// '~' decltype-specifier [TODO]
1084/// template-id [TODO]
1085///
1086Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
1087 bool mayHaveIdentifier,
1088 bool mayHaveDirectInit,
1089 bool mayHaveTrailingReturnType) {
1090 // declarator:
1091 // direct-declarator
1092 // ptr-operator declarator
1093 if (TryParsePtrOperatorSeq() == TPResult::Error)
1094 return TPResult::Error;
1095
1096 // direct-declarator:
1097 // direct-abstract-declarator:
1098 if (Tok.is(tok::ellipsis))
1099 ConsumeToken();
1100
1101 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
1102 (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||
1103 NextToken().is(tok::kw_operator)))) &&
1104 mayHaveIdentifier) {
1105 // declarator-id
1106 if (Tok.is(tok::annot_cxxscope)) {
1107 CXXScopeSpec SS;
1109 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
1110 if (SS.isInvalid())
1111 return TPResult::Error;
1112 ConsumeAnnotationToken();
1113 } else if (Tok.is(tok::identifier)) {
1114 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
1115 }
1116 if (Tok.is(tok::kw_operator)) {
1117 if (TryParseOperatorId() == TPResult::Error)
1118 return TPResult::Error;
1119 } else
1120 ConsumeToken();
1121 } else if (Tok.is(tok::l_paren)) {
1122 ConsumeParen();
1123 if (mayBeAbstract &&
1124 (Tok.is(tok::r_paren) || // 'int()' is a function.
1125 // 'int(...)' is a function.
1126 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
1127 isDeclarationSpecifier(
1128 ImplicitTypenameContext::No))) { // 'int(int)' is a function.
1129 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1130 // exception-specification[opt]
1131 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1132 if (TPR != TPResult::Ambiguous)
1133 return TPR;
1134 } else {
1135 // '(' declarator ')'
1136 // '(' attributes declarator ')'
1137 // '(' abstract-declarator ')'
1138 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
1139 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
1140 tok::kw___regcall, tok::kw___vectorcall))
1141 return TPResult::True; // attributes indicate declaration
1142 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1143 if (TPR != TPResult::Ambiguous)
1144 return TPR;
1145 if (Tok.isNot(tok::r_paren))
1146 return TPResult::False;
1147 ConsumeParen();
1148 }
1149 } else if (!mayBeAbstract) {
1150 return TPResult::False;
1151 }
1152
1153 if (mayHaveDirectInit)
1154 return TPResult::Ambiguous;
1155
1156 while (true) {
1157 TPResult TPR(TPResult::Ambiguous);
1158
1159 if (Tok.is(tok::l_paren)) {
1160 // Check whether we have a function declarator or a possible ctor-style
1161 // initializer that follows the declarator. Note that ctor-style
1162 // initializers are not possible in contexts where abstract declarators
1163 // are allowed.
1164 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1165 break;
1166
1167 // direct-declarator '(' parameter-declaration-clause ')'
1168 // cv-qualifier-seq[opt] exception-specification[opt]
1169 ConsumeParen();
1170 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1171 } else if (Tok.is(tok::l_square)) {
1172 // direct-declarator '[' constant-expression[opt] ']'
1173 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
1174 TPR = TryParseBracketDeclarator();
1175 } else if (Tok.is(tok::kw_requires)) {
1176 // declarator requires-clause
1177 // A requires clause indicates a function declaration.
1178 TPR = TPResult::True;
1179 } else {
1180 break;
1181 }
1182
1183 if (TPR != TPResult::Ambiguous)
1184 return TPR;
1185 }
1186
1187 return TPResult::Ambiguous;
1188}
1189
1190bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
1191 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1192}
1193
1194namespace {
1195class TentativeParseCCC final : public CorrectionCandidateCallback {
1196public:
1197 TentativeParseCCC(const Token &Next) {
1198 WantRemainingKeywords = false;
1199 WantTypeSpecifiers =
1200 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1201 tok::identifier, tok::comma);
1202 }
1203
1204 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1205 // Reject any candidate that only resolves to instance members since they
1206 // aren't viable as standalone identifiers instead of member references.
1207 if (Candidate.isResolved() && !Candidate.isKeyword() &&
1208 llvm::all_of(Candidate,
1209 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1210 return false;
1211
1213 }
1214
1215 std::unique_ptr<CorrectionCandidateCallback> clone() override {
1216 return std::make_unique<TentativeParseCCC>(*this);
1217 }
1218};
1219}
1220/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
1221/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
1222/// be either a decl-specifier or a function-style cast, and TPResult::Error
1223/// if a parsing error was found and reported.
1224///
1225/// If InvalidAsDeclSpec is not null, some cases that would be ill-formed as
1226/// declaration specifiers but possibly valid as some other kind of construct
1227/// return TPResult::Ambiguous instead of TPResult::False. When this happens,
1228/// the intent is to keep trying to disambiguate, on the basis that we might
1229/// find a better reason to treat this construct as a declaration later on.
1230/// When this happens and the name could possibly be valid in some other
1231/// syntactic context, *InvalidAsDeclSpec is set to 'true'. The current cases
1232/// that trigger this are:
1233///
1234/// * When parsing X::Y (with no 'typename') where X is dependent
1235/// * When parsing X<Y> where X is undeclared
1236///
1237/// decl-specifier:
1238/// storage-class-specifier
1239/// type-specifier
1240/// function-specifier
1241/// 'friend'
1242/// 'typedef'
1243/// [C++11] 'constexpr'
1244/// [C++20] 'consteval'
1245/// [GNU] attributes declaration-specifiers[opt]
1246///
1247/// storage-class-specifier:
1248/// 'register'
1249/// 'static'
1250/// 'extern'
1251/// 'mutable'
1252/// 'auto'
1253/// [GNU] '__thread'
1254/// [C++11] 'thread_local'
1255/// [C11] '_Thread_local'
1256///
1257/// function-specifier:
1258/// 'inline'
1259/// 'virtual'
1260/// 'explicit'
1261///
1262/// typedef-name:
1263/// identifier
1264///
1265/// type-specifier:
1266/// simple-type-specifier
1267/// class-specifier
1268/// enum-specifier
1269/// elaborated-type-specifier
1270/// typename-specifier
1271/// cv-qualifier
1272///
1273/// simple-type-specifier:
1274/// '::'[opt] nested-name-specifier[opt] type-name
1275/// '::'[opt] nested-name-specifier 'template'
1276/// simple-template-id [TODO]
1277/// 'char'
1278/// 'wchar_t'
1279/// 'bool'
1280/// 'short'
1281/// 'int'
1282/// 'long'
1283/// 'signed'
1284/// 'unsigned'
1285/// 'float'
1286/// 'double'
1287/// 'void'
1288/// [GNU] typeof-specifier
1289/// [GNU] '_Complex'
1290/// [C++11] 'auto'
1291/// [GNU] '__auto_type'
1292/// [C++11] 'decltype' ( expression )
1293/// [C++1y] 'decltype' ( 'auto' )
1294///
1295/// type-name:
1296/// class-name
1297/// enum-name
1298/// typedef-name
1299///
1300/// elaborated-type-specifier:
1301/// class-key '::'[opt] nested-name-specifier[opt] identifier
1302/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
1303/// simple-template-id
1304/// 'enum' '::'[opt] nested-name-specifier[opt] identifier
1305///
1306/// enum-name:
1307/// identifier
1308///
1309/// enum-specifier:
1310/// 'enum' identifier[opt] '{' enumerator-list[opt] '}'
1311/// 'enum' identifier[opt] '{' enumerator-list ',' '}'
1312///
1313/// class-specifier:
1314/// class-head '{' member-specification[opt] '}'
1315///
1316/// class-head:
1317/// class-key identifier[opt] base-clause[opt]
1318/// class-key nested-name-specifier identifier base-clause[opt]
1319/// class-key nested-name-specifier[opt] simple-template-id
1320/// base-clause[opt]
1321///
1322/// class-key:
1323/// 'class'
1324/// 'struct'
1325/// 'union'
1326///
1327/// cv-qualifier:
1328/// 'const'
1329/// 'volatile'
1330/// [GNU] restrict
1331///
1332Parser::TPResult
1333Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
1334 Parser::TPResult BracedCastResult,
1335 bool *InvalidAsDeclSpec) {
1336 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1337 int Lookahead) {
1338 // We have a placeholder-constraint (we check for 'auto' or 'decltype' to
1339 // distinguish 'C<int>;' from 'C<int> auto c = 1;')
1340 return TemplateId->Kind == TNK_Concept_template &&
1341 (GetLookAheadToken(Lookahead + 1)
1342 .isOneOf(tok::kw_auto, tok::kw_decltype,
1343 // If we have an identifier here, the user probably
1344 // forgot the 'auto' in the placeholder constraint,
1345 // e.g. 'C<int> x = 2;' This will be diagnosed nicely
1346 // later, so disambiguate as a declaration.
1347 tok::identifier,
1348 // CVR qualifierslikely the same situation for the
1349 // user, so let this be diagnosed nicely later. We
1350 // cannot handle references here, as `C<int> & Other`
1351 // and `C<int> && Other` are both legal.
1352 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1353 // While `C<int> && Other` is legal, doing so while not specifying a
1354 // template argument is NOT, so see if we can fix up in that case at
1355 // minimum. Concepts require at least 1 template parameter, so we
1356 // can count on the argument count.
1357 // FIXME: In the future, we migth be able to have SEMA look up the
1358 // declaration for this concept, and see how many template
1359 // parameters it has. If the concept isn't fully specified, it is
1360 // possibly a situation where we want deduction, such as:
1361 // `BinaryConcept<int> auto f = bar();`
1362 (TemplateId->NumArgs == 0 &&
1363 GetLookAheadToken(Lookahead + 1).isOneOf(tok::amp, tok::ampamp)));
1364 };
1365 switch (Tok.getKind()) {
1366 case tok::identifier: {
1367 if (GetLookAheadToken(1).is(tok::ellipsis) &&
1368 GetLookAheadToken(2).is(tok::l_square)) {
1369
1371 return TPResult::Error;
1372 if (Tok.is(tok::identifier))
1373 return TPResult::False;
1374 return isCXXDeclarationSpecifier(ImplicitTypenameContext::No,
1375 BracedCastResult, InvalidAsDeclSpec);
1376 }
1377
1378 // Check for need to substitute AltiVec __vector keyword
1379 // for "vector" identifier.
1380 if (TryAltiVecVectorToken())
1381 return TPResult::True;
1382
1383 const Token &Next = NextToken();
1384 // In 'foo bar', 'foo' is always a type name outside of Objective-C.
1385 if (!getLangOpts().ObjC && Next.is(tok::identifier))
1386 return TPResult::True;
1387
1388 // If this identifier was reverted from a token ID, and the next token
1389 // is a '(', we assume it to be a use of a type trait, so this
1390 // can never be a type name.
1391 if (Next.is(tok::l_paren) &&
1393 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1394 return TPResult::False;
1395 }
1396
1397 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1398 // Determine whether this is a valid expression. If not, we will hit
1399 // a parse error one way or another. In that case, tell the caller that
1400 // this is ambiguous. Typo-correct to type and expression keywords and
1401 // to types and identifiers, in order to try to recover from errors.
1402 TentativeParseCCC CCC(Next);
1403 switch (TryAnnotateName(&CCC)) {
1404 case ANK_Error:
1405 return TPResult::Error;
1406 case ANK_TentativeDecl:
1407 return TPResult::False;
1408 case ANK_TemplateName:
1409 // In C++17, this could be a type template for class template argument
1410 // deduction. Try to form a type annotation for it. If we're in a
1411 // template template argument, we'll undo this when checking the
1412 // validity of the argument.
1413 if (getLangOpts().CPlusPlus17) {
1414 if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
1415 return TPResult::Error;
1416 if (Tok.isNot(tok::identifier))
1417 break;
1418 }
1419
1420 // A bare type template-name which can't be a template template
1421 // argument is an error, and was probably intended to be a type.
1422 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1423 case ANK_Unresolved:
1424 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1425 case ANK_Success:
1426 break;
1427 }
1428 assert(Tok.isNot(tok::identifier) &&
1429 "TryAnnotateName succeeded without producing an annotation");
1430 } else {
1431 // This might possibly be a type with a dependent scope specifier and
1432 // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
1433 // since it will annotate as a primary expression, and we want to use the
1434 // "missing 'typename'" logic.
1435 if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
1436 return TPResult::Error;
1437 // If annotation failed, assume it's a non-type.
1438 // FIXME: If this happens due to an undeclared identifier, treat it as
1439 // ambiguous.
1440 if (Tok.is(tok::identifier))
1441 return TPResult::False;
1442 }
1443
1444 // We annotated this token as something. Recurse to handle whatever we got.
1445 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1446 InvalidAsDeclSpec);
1447 }
1448
1449 case tok::kw_typename: // typename T::type
1450 // Annotate typenames and C++ scope specifiers. If we get one, just
1451 // recurse to handle whatever we get.
1453 return TPResult::Error;
1454 return isCXXDeclarationSpecifier(ImplicitTypenameContext::Yes,
1455 BracedCastResult, InvalidAsDeclSpec);
1456
1457 case tok::kw_auto: {
1458 if (!getLangOpts().CPlusPlus23)
1459 return TPResult::True;
1460 if (NextToken().is(tok::l_brace))
1461 return TPResult::False;
1462 if (NextToken().is(tok::l_paren))
1463 return TPResult::Ambiguous;
1464 return TPResult::True;
1465 }
1466
1467 case tok::coloncolon: { // ::foo::bar
1468 const Token &Next = NextToken();
1469 if (Next.isOneOf(tok::kw_new, // ::new
1470 tok::kw_delete)) // ::delete
1471 return TPResult::False;
1472 [[fallthrough]];
1473 }
1474 case tok::kw___super:
1475 case tok::kw_decltype:
1476 // Annotate typenames and C++ scope specifiers. If we get one, just
1477 // recurse to handle whatever we get.
1478 if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
1479 return TPResult::Error;
1480 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1481 InvalidAsDeclSpec);
1482
1483 // decl-specifier:
1484 // storage-class-specifier
1485 // type-specifier
1486 // function-specifier
1487 // 'friend'
1488 // 'typedef'
1489 // 'constexpr'
1490 case tok::kw_friend:
1491 case tok::kw_typedef:
1492 case tok::kw_constexpr:
1493 case tok::kw_consteval:
1494 case tok::kw_constinit:
1495 // storage-class-specifier
1496 case tok::kw_register:
1497 case tok::kw_static:
1498 case tok::kw_extern:
1499 case tok::kw_mutable:
1500 case tok::kw___thread:
1501 case tok::kw_thread_local:
1502 case tok::kw__Thread_local:
1503 // function-specifier
1504 case tok::kw_inline:
1505 case tok::kw_virtual:
1506 case tok::kw_explicit:
1507
1508 // Modules
1509 case tok::kw___module_private__:
1510
1511 // Debugger support
1512 case tok::kw___unknown_anytype:
1513
1514 // type-specifier:
1515 // simple-type-specifier
1516 // class-specifier
1517 // enum-specifier
1518 // elaborated-type-specifier
1519 // typename-specifier
1520 // cv-qualifier
1521
1522 // class-specifier
1523 // elaborated-type-specifier
1524 case tok::kw_class:
1525 case tok::kw_struct:
1526 case tok::kw_union:
1527 case tok::kw___interface:
1528 // enum-specifier
1529 case tok::kw_enum:
1530 // cv-qualifier
1531 case tok::kw_const:
1532 case tok::kw_volatile:
1533 return TPResult::True;
1534
1535 // OpenCL address space qualifiers
1536 case tok::kw_private:
1537 if (!getLangOpts().OpenCL)
1538 return TPResult::False;
1539 [[fallthrough]];
1540 case tok::kw___private:
1541 case tok::kw___local:
1542 case tok::kw___global:
1543 case tok::kw___constant:
1544 case tok::kw___generic:
1545 // OpenCL access qualifiers
1546 case tok::kw___read_only:
1547 case tok::kw___write_only:
1548 case tok::kw___read_write:
1549 // OpenCL pipe
1550 case tok::kw_pipe:
1551
1552 // HLSL address space qualifiers
1553 case tok::kw_groupshared:
1554 case tok::kw_in:
1555 case tok::kw_inout:
1556 case tok::kw_out:
1557
1558 // GNU
1559 case tok::kw_restrict:
1560 case tok::kw__Complex:
1561 case tok::kw___attribute:
1562 case tok::kw___auto_type:
1563 return TPResult::True;
1564
1565 // Microsoft
1566 case tok::kw___declspec:
1567 case tok::kw___cdecl:
1568 case tok::kw___stdcall:
1569 case tok::kw___fastcall:
1570 case tok::kw___thiscall:
1571 case tok::kw___regcall:
1572 case tok::kw___vectorcall:
1573 case tok::kw___w64:
1574 case tok::kw___sptr:
1575 case tok::kw___uptr:
1576 case tok::kw___ptr64:
1577 case tok::kw___ptr32:
1578 case tok::kw___forceinline:
1579 case tok::kw___unaligned:
1580 case tok::kw__Nonnull:
1581 case tok::kw__Nullable:
1582 case tok::kw__Nullable_result:
1583 case tok::kw__Null_unspecified:
1584 case tok::kw___kindof:
1585 return TPResult::True;
1586
1587 // WebAssemblyFuncref
1588 case tok::kw___funcref:
1589 return TPResult::True;
1590
1591 // Borland
1592 case tok::kw___pascal:
1593 return TPResult::True;
1594
1595 // AltiVec
1596 case tok::kw___vector:
1597 return TPResult::True;
1598
1599 case tok::kw_this: {
1600 // Try to parse a C++23 Explicit Object Parameter
1601 // We do that in all language modes to produce a better diagnostic.
1602 if (getLangOpts().CPlusPlus) {
1603 RevertingTentativeParsingAction PA(*this);
1604 ConsumeToken();
1605 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1606 InvalidAsDeclSpec);
1607 }
1608 return TPResult::False;
1609 }
1610 case tok::annot_template_id: {
1611 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1612 // If lookup for the template-name found nothing, don't assume we have a
1613 // definitive disambiguation result yet.
1614 if ((TemplateId->hasInvalidName() ||
1615 TemplateId->Kind == TNK_Undeclared_template) &&
1616 InvalidAsDeclSpec) {
1617 // 'template-id(' can be a valid expression but not a valid decl spec if
1618 // the template-name is not declared, but we don't consider this to be a
1619 // definitive disambiguation. In any other context, it's an error either
1620 // way.
1621 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
1622 return TPResult::Ambiguous;
1623 }
1624 if (TemplateId->hasInvalidName())
1625 return TPResult::Error;
1626 if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0))
1627 return TPResult::True;
1628 if (TemplateId->Kind != TNK_Type_template)
1629 return TPResult::False;
1630 CXXScopeSpec SS;
1631 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1632 assert(Tok.is(tok::annot_typename));
1633 goto case_typename;
1634 }
1635
1636 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
1637 // We've already annotated a scope; try to annotate a type.
1638 if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
1639 return TPResult::Error;
1640 if (!Tok.is(tok::annot_typename)) {
1641 if (Tok.is(tok::annot_cxxscope) &&
1642 NextToken().is(tok::annot_template_id)) {
1643 TemplateIdAnnotation *TemplateId =
1644 takeTemplateIdAnnotation(NextToken());
1645 if (TemplateId->hasInvalidName()) {
1646 if (InvalidAsDeclSpec) {
1647 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
1648 return TPResult::Ambiguous;
1649 }
1650 return TPResult::Error;
1651 }
1652 if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1))
1653 return TPResult::True;
1654 }
1655 // If the next token is an identifier or a type qualifier, then this
1656 // can't possibly be a valid expression either.
1657 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
1658 CXXScopeSpec SS;
1660 Tok.getAnnotationRange(),
1661 SS);
1662 if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
1663 RevertingTentativeParsingAction PA(*this);
1664 ConsumeAnnotationToken();
1665 ConsumeToken();
1666 bool isIdentifier = Tok.is(tok::identifier);
1667 TPResult TPR = TPResult::False;
1668 if (!isIdentifier)
1669 TPR = isCXXDeclarationSpecifier(
1670 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1671
1672 if (isIdentifier ||
1673 TPR == TPResult::True || TPR == TPResult::Error)
1674 return TPResult::Error;
1675
1676 if (InvalidAsDeclSpec) {
1677 // We can't tell whether this is a missing 'typename' or a valid
1678 // expression.
1679 *InvalidAsDeclSpec = true;
1680 return TPResult::Ambiguous;
1681 } else {
1682 // In MS mode, if InvalidAsDeclSpec is not provided, and the tokens
1683 // are or the form *) or &) *> or &> &&>, this can't be an expression.
1684 // The typename must be missing.
1685 if (getLangOpts().MSVCCompat) {
1686 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1687 (NextToken().is(tok::r_paren) ||
1688 NextToken().is(tok::greater))) ||
1689 (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
1690 return TPResult::True;
1691 }
1692 }
1693 } else {
1694 // Try to resolve the name. If it doesn't exist, assume it was
1695 // intended to name a type and keep disambiguating.
1696 switch (TryAnnotateName(/*CCC=*/nullptr, AllowImplicitTypename)) {
1697 case ANK_Error:
1698 return TPResult::Error;
1699 case ANK_TentativeDecl:
1700 return TPResult::False;
1701 case ANK_TemplateName:
1702 // In C++17, this could be a type template for class template
1703 // argument deduction.
1704 if (getLangOpts().CPlusPlus17) {
1706 return TPResult::Error;
1707 // If we annotated then the current token should not still be ::
1708 // FIXME we may want to also check for tok::annot_typename but
1709 // currently don't have a test case.
1710 if (Tok.isNot(tok::annot_cxxscope))
1711 break;
1712 }
1713
1714 // A bare type template-name which can't be a template template
1715 // argument is an error, and was probably intended to be a type.
1716 // In C++17, this could be class template argument deduction.
1717 return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1718 ? TPResult::True
1719 : TPResult::False;
1720 case ANK_Unresolved:
1721 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1722 case ANK_Success:
1723 break;
1724 }
1725
1726 // Annotated it, check again.
1727 assert(Tok.isNot(tok::annot_cxxscope) ||
1728 NextToken().isNot(tok::identifier));
1729 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1730 BracedCastResult, InvalidAsDeclSpec);
1731 }
1732 }
1733 return TPResult::False;
1734 }
1735 // If that succeeded, fallthrough into the generic simple-type-id case.
1736 [[fallthrough]];
1737
1738 // The ambiguity resides in a simple-type-specifier/typename-specifier
1739 // followed by a '('. The '(' could either be the start of:
1740 //
1741 // direct-declarator:
1742 // '(' declarator ')'
1743 //
1744 // direct-abstract-declarator:
1745 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1746 // exception-specification[opt]
1747 // '(' abstract-declarator ')'
1748 //
1749 // or part of a function-style cast expression:
1750 //
1751 // simple-type-specifier '(' expression-list[opt] ')'
1752 //
1753
1754 // simple-type-specifier:
1755
1756 case tok::annot_typename:
1757 case_typename:
1758 // In Objective-C, we might have a protocol-qualified type.
1759 if (getLangOpts().ObjC && NextToken().is(tok::less)) {
1760 // Tentatively parse the protocol qualifiers.
1761 RevertingTentativeParsingAction PA(*this);
1762 ConsumeAnyToken(); // The type token
1763
1764 TPResult TPR = TryParseProtocolQualifiers();
1765 bool isFollowedByParen = Tok.is(tok::l_paren);
1766 bool isFollowedByBrace = Tok.is(tok::l_brace);
1767
1768 if (TPR == TPResult::Error)
1769 return TPResult::Error;
1770
1771 if (isFollowedByParen)
1772 return TPResult::Ambiguous;
1773
1774 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
1775 return BracedCastResult;
1776
1777 return TPResult::True;
1778 }
1779
1780 [[fallthrough]];
1781
1782 case tok::kw_char:
1783 case tok::kw_wchar_t:
1784 case tok::kw_char8_t:
1785 case tok::kw_char16_t:
1786 case tok::kw_char32_t:
1787 case tok::kw_bool:
1788 case tok::kw_short:
1789 case tok::kw_int:
1790 case tok::kw_long:
1791 case tok::kw___int64:
1792 case tok::kw___int128:
1793 case tok::kw_signed:
1794 case tok::kw_unsigned:
1795 case tok::kw_half:
1796 case tok::kw_float:
1797 case tok::kw_double:
1798 case tok::kw___bf16:
1799 case tok::kw__Float16:
1800 case tok::kw___float128:
1801 case tok::kw___ibm128:
1802 case tok::kw_void:
1803 case tok::annot_decltype:
1804 case tok::kw__Accum:
1805 case tok::kw__Fract:
1806 case tok::kw__Sat:
1807 case tok::annot_pack_indexing_type:
1808#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1809#include "clang/Basic/OpenCLImageTypes.def"
1810 if (NextToken().is(tok::l_paren))
1811 return TPResult::Ambiguous;
1812
1813 // This is a function-style cast in all cases we disambiguate other than
1814 // one:
1815 // struct S {
1816 // enum E : int { a = 4 }; // enum
1817 // enum E : int { 4 }; // bit-field
1818 // };
1819 if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
1820 return BracedCastResult;
1821
1822 if (isStartOfObjCClassMessageMissingOpenBracket())
1823 return TPResult::False;
1824
1825 return TPResult::True;
1826
1827 // GNU typeof support.
1828 case tok::kw_typeof: {
1829 if (NextToken().isNot(tok::l_paren))
1830 return TPResult::True;
1831
1832 RevertingTentativeParsingAction PA(*this);
1833
1834 TPResult TPR = TryParseTypeofSpecifier();
1835 bool isFollowedByParen = Tok.is(tok::l_paren);
1836 bool isFollowedByBrace = Tok.is(tok::l_brace);
1837
1838 if (TPR == TPResult::Error)
1839 return TPResult::Error;
1840
1841 if (isFollowedByParen)
1842 return TPResult::Ambiguous;
1843
1844 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
1845 return BracedCastResult;
1846
1847 return TPResult::True;
1848 }
1849
1850#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1851#include "clang/Basic/TransformTypeTraits.def"
1852 return TPResult::True;
1853
1854 // C11 _Alignas
1855 case tok::kw__Alignas:
1856 return TPResult::True;
1857 // C11 _Atomic
1858 case tok::kw__Atomic:
1859 return TPResult::True;
1860
1861 case tok::kw__BitInt:
1862 case tok::kw__ExtInt: {
1863 if (NextToken().isNot(tok::l_paren))
1864 return TPResult::Error;
1865 RevertingTentativeParsingAction PA(*this);
1866 ConsumeToken();
1867 ConsumeParen();
1868
1869 if (!SkipUntil(tok::r_paren, StopAtSemi))
1870 return TPResult::Error;
1871
1872 if (Tok.is(tok::l_paren))
1873 return TPResult::Ambiguous;
1874
1875 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
1876 return BracedCastResult;
1877
1878 return TPResult::True;
1879 }
1880 default:
1881 return TPResult::False;
1882 }
1883}
1884
1885bool Parser::isCXXDeclarationSpecifierAType() {
1886 switch (Tok.getKind()) {
1887 // typename-specifier
1888 case tok::annot_decltype:
1889 case tok::annot_pack_indexing_type:
1890 case tok::annot_template_id:
1891 case tok::annot_typename:
1892 case tok::kw_typeof:
1893#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1894#include "clang/Basic/TransformTypeTraits.def"
1895 return true;
1896
1897 // elaborated-type-specifier
1898 case tok::kw_class:
1899 case tok::kw_struct:
1900 case tok::kw_union:
1901 case tok::kw___interface:
1902 case tok::kw_enum:
1903 return true;
1904
1905 // simple-type-specifier
1906 case tok::kw_char:
1907 case tok::kw_wchar_t:
1908 case tok::kw_char8_t:
1909 case tok::kw_char16_t:
1910 case tok::kw_char32_t:
1911 case tok::kw_bool:
1912 case tok::kw_short:
1913 case tok::kw_int:
1914 case tok::kw__ExtInt:
1915 case tok::kw__BitInt:
1916 case tok::kw_long:
1917 case tok::kw___int64:
1918 case tok::kw___int128:
1919 case tok::kw_signed:
1920 case tok::kw_unsigned:
1921 case tok::kw_half:
1922 case tok::kw_float:
1923 case tok::kw_double:
1924 case tok::kw___bf16:
1925 case tok::kw__Float16:
1926 case tok::kw___float128:
1927 case tok::kw___ibm128:
1928 case tok::kw_void:
1929 case tok::kw___unknown_anytype:
1930 case tok::kw___auto_type:
1931 case tok::kw__Accum:
1932 case tok::kw__Fract:
1933 case tok::kw__Sat:
1934#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1935#include "clang/Basic/OpenCLImageTypes.def"
1936 return true;
1937
1938 case tok::kw_auto:
1939 return getLangOpts().CPlusPlus11;
1940
1941 case tok::kw__Atomic:
1942 // "_Atomic foo"
1943 return NextToken().is(tok::l_paren);
1944
1945 default:
1946 return false;
1947 }
1948}
1949
1950/// [GNU] typeof-specifier:
1951/// 'typeof' '(' expressions ')'
1952/// 'typeof' '(' type-name ')'
1953///
1954Parser::TPResult Parser::TryParseTypeofSpecifier() {
1955 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
1956 ConsumeToken();
1957
1958 assert(Tok.is(tok::l_paren) && "Expected '('");
1959 // Parse through the parens after 'typeof'.
1960 ConsumeParen();
1961 if (!SkipUntil(tok::r_paren, StopAtSemi))
1962 return TPResult::Error;
1963
1964 return TPResult::Ambiguous;
1965}
1966
1967/// [ObjC] protocol-qualifiers:
1968//// '<' identifier-list '>'
1969Parser::TPResult Parser::TryParseProtocolQualifiers() {
1970 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
1971 ConsumeToken();
1972 do {
1973 if (Tok.isNot(tok::identifier))
1974 return TPResult::Error;
1975 ConsumeToken();
1976
1977 if (Tok.is(tok::comma)) {
1978 ConsumeToken();
1979 continue;
1980 }
1981
1982 if (Tok.is(tok::greater)) {
1983 ConsumeToken();
1984 return TPResult::Ambiguous;
1985 }
1986 } while (false);
1987
1988 return TPResult::Error;
1989}
1990
1991/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
1992/// a constructor-style initializer, when parsing declaration statements.
1993/// Returns true for function declarator and false for constructor-style
1994/// initializer.
1995/// If during the disambiguation process a parsing error is encountered,
1996/// the function returns true to let the declaration parsing code handle it.
1997///
1998/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1999/// exception-specification[opt]
2000///
2001bool Parser::isCXXFunctionDeclarator(
2002 bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) {
2003
2004 // C++ 8.2p1:
2005 // The ambiguity arising from the similarity between a function-style cast and
2006 // a declaration mentioned in 6.8 can also occur in the context of a
2007 // declaration. In that context, the choice is between a function declaration
2008 // with a redundant set of parentheses around a parameter name and an object
2009 // declaration with a function-style cast as the initializer. Just as for the
2010 // ambiguities mentioned in 6.8, the resolution is to consider any construct
2011 // that could possibly be a declaration a declaration.
2012
2013 RevertingTentativeParsingAction PA(*this);
2014
2015 ConsumeParen();
2016 bool InvalidAsDeclaration = false;
2017 TPResult TPR = TryParseParameterDeclarationClause(
2018 &InvalidAsDeclaration, /*VersusTemplateArgument=*/false,
2019 AllowImplicitTypename);
2020 if (TPR == TPResult::Ambiguous) {
2021 if (Tok.isNot(tok::r_paren))
2022 TPR = TPResult::False;
2023 else {
2024 const Token &Next = NextToken();
2025 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
2026 tok::kw_throw, tok::kw_noexcept, tok::l_square,
2027 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
2028 isCXX11VirtSpecifier(Next))
2029 // The next token cannot appear after a constructor-style initializer,
2030 // and can appear next in a function definition. This must be a function
2031 // declarator.
2032 TPR = TPResult::True;
2033 else if (InvalidAsDeclaration)
2034 // Use the absence of 'typename' as a tie-breaker.
2035 TPR = TPResult::False;
2036 }
2037 }
2038
2039 if (IsAmbiguous && TPR == TPResult::Ambiguous)
2040 *IsAmbiguous = true;
2041
2042 // In case of an error, let the declaration parsing code handle it.
2043 return TPR != TPResult::False;
2044}
2045
2046/// parameter-declaration-clause:
2047/// parameter-declaration-list[opt] '...'[opt]
2048/// parameter-declaration-list ',' '...'
2049///
2050/// parameter-declaration-list:
2051/// parameter-declaration
2052/// parameter-declaration-list ',' parameter-declaration
2053///
2054/// parameter-declaration:
2055/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
2056/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
2057/// '=' assignment-expression
2058/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
2059/// attributes[opt]
2060/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
2061/// attributes[opt] '=' assignment-expression
2062///
2063Parser::TPResult Parser::TryParseParameterDeclarationClause(
2064 bool *InvalidAsDeclaration, bool VersusTemplateArgument,
2065 ImplicitTypenameContext AllowImplicitTypename) {
2066
2067 if (Tok.is(tok::r_paren))
2068 return TPResult::Ambiguous;
2069
2070 // parameter-declaration-list[opt] '...'[opt]
2071 // parameter-declaration-list ',' '...'
2072 //
2073 // parameter-declaration-list:
2074 // parameter-declaration
2075 // parameter-declaration-list ',' parameter-declaration
2076 //
2077 while (true) {
2078 // '...'[opt]
2079 if (Tok.is(tok::ellipsis)) {
2080 ConsumeToken();
2081 if (Tok.is(tok::r_paren))
2082 return TPResult::True; // '...)' is a sign of a function declarator.
2083 else
2084 return TPResult::False;
2085 }
2086
2087 // An attribute-specifier-seq here is a sign of a function declarator.
2088 if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
2089 /*OuterMightBeMessageSend*/true))
2090 return TPResult::True;
2091
2092 ParsedAttributes attrs(AttrFactory);
2093 MaybeParseMicrosoftAttributes(attrs);
2094
2095 // decl-specifier-seq
2096 // A parameter-declaration's initializer must be preceded by an '=', so
2097 // decl-specifier-seq '{' is not a parameter in C++11.
2098 TPResult TPR = isCXXDeclarationSpecifier(
2099 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2100 // A declaration-specifier (not followed by '(' or '{') means this can't be
2101 // an expression, but it could still be a template argument.
2102 if (TPR != TPResult::Ambiguous &&
2103 !(VersusTemplateArgument && TPR == TPResult::True))
2104 return TPR;
2105
2106 bool SeenType = false;
2107 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
2108 do {
2109 SeenType |= isCXXDeclarationSpecifierAType();
2110 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2111 return TPResult::Error;
2112
2113 // If we see a parameter name, this can't be a template argument.
2114 if (SeenType && Tok.is(tok::identifier))
2115 return TPResult::True;
2116
2117 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2118 InvalidAsDeclaration);
2119 if (TPR == TPResult::Error)
2120 return TPR;
2121
2122 // Two declaration-specifiers means this can't be an expression.
2123 if (TPR == TPResult::True && !VersusTemplateArgument)
2124 return TPR;
2125 } while (TPR != TPResult::False);
2126
2127 // declarator
2128 // abstract-declarator[opt]
2129 TPR = TryParseDeclarator(
2130 /*mayBeAbstract=*/true,
2131 /*mayHaveIdentifier=*/true,
2132 /*mayHaveDirectInit=*/false,
2133 /*mayHaveTrailingReturnType=*/DeclarationSpecifierIsAuto);
2134 if (TPR != TPResult::Ambiguous)
2135 return TPR;
2136
2137 // [GNU] attributes[opt]
2138 if (Tok.is(tok::kw___attribute))
2139 return TPResult::True;
2140
2141 // If we're disambiguating a template argument in a default argument in
2142 // a class definition versus a parameter declaration, an '=' here
2143 // disambiguates the parse one way or the other.
2144 // If this is a parameter, it must have a default argument because
2145 // (a) the previous parameter did, and
2146 // (b) this must be the first declaration of the function, so we can't
2147 // inherit any default arguments from elsewhere.
2148 // FIXME: If we reach a ')' without consuming any '>'s, then this must
2149 // also be a function parameter (that's missing its default argument).
2150 if (VersusTemplateArgument)
2151 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
2152
2153 if (Tok.is(tok::equal)) {
2154 // '=' assignment-expression
2155 // Parse through assignment-expression.
2156 if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
2157 return TPResult::Error;
2158 }
2159
2160 if (Tok.is(tok::ellipsis)) {
2161 ConsumeToken();
2162 if (Tok.is(tok::r_paren))
2163 return TPResult::True; // '...)' is a sign of a function declarator.
2164 else
2165 return TPResult::False;
2166 }
2167
2168 if (!TryConsumeToken(tok::comma))
2169 break;
2170 }
2171
2172 return TPResult::Ambiguous;
2173}
2174
2175/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
2176/// parsing as a function declarator.
2177/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
2178/// return TPResult::Ambiguous, otherwise it will return either False() or
2179/// Error().
2180///
2181/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
2182/// exception-specification[opt]
2183///
2184/// exception-specification:
2185/// 'throw' '(' type-id-list[opt] ')'
2186///
2187Parser::TPResult
2188Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
2189 // The '(' is already parsed.
2190
2191 TPResult TPR = TryParseParameterDeclarationClause();
2192 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
2193 TPR = TPResult::False;
2194
2195 if (TPR == TPResult::False || TPR == TPResult::Error)
2196 return TPR;
2197
2198 // Parse through the parens.
2199 if (!SkipUntil(tok::r_paren, StopAtSemi))
2200 return TPResult::Error;
2201
2202 // cv-qualifier-seq
2203 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2204 tok::kw_restrict))
2205 ConsumeToken();
2206
2207 // ref-qualifier[opt]
2208 if (Tok.isOneOf(tok::amp, tok::ampamp))
2209 ConsumeToken();
2210
2211 // exception-specification
2212 if (Tok.is(tok::kw_throw)) {
2213 ConsumeToken();
2214 if (Tok.isNot(tok::l_paren))
2215 return TPResult::Error;
2216
2217 // Parse through the parens after 'throw'.
2218 ConsumeParen();
2219 if (!SkipUntil(tok::r_paren, StopAtSemi))
2220 return TPResult::Error;
2221 }
2222 if (Tok.is(tok::kw_noexcept)) {
2223 ConsumeToken();
2224 // Possibly an expression as well.
2225 if (Tok.is(tok::l_paren)) {
2226 // Find the matching rparen.
2227 ConsumeParen();
2228 if (!SkipUntil(tok::r_paren, StopAtSemi))
2229 return TPResult::Error;
2230 }
2231 }
2232
2233 // attribute-specifier-seq
2234 if (!TrySkipAttributes())
2235 return TPResult::Ambiguous;
2236
2237 // trailing-return-type
2238 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
2239 if (TPR == TPResult::True)
2240 return TPR;
2241 ConsumeToken();
2242 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
2243 return TPResult::False;
2244 }
2245 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2246 return TPResult::True;
2247 }
2248
2249 return TPResult::Ambiguous;
2250}
2251
2252// When parsing an identifier after an arrow it may be a member expression,
2253// in which case we should not annotate it as an independant expression
2254// so we just lookup that name, if it's not a type the construct is not
2255// a function declaration.
2256bool Parser::NameAfterArrowIsNonType() {
2257 assert(Tok.is(tok::identifier));
2258 Token Next = NextToken();
2259 if (Next.is(tok::coloncolon))
2260 return false;
2261 IdentifierInfo *Name = Tok.getIdentifierInfo();
2262 SourceLocation NameLoc = Tok.getLocation();
2263 CXXScopeSpec SS;
2264 TentativeParseCCC CCC(Next);
2265 Sema::NameClassification Classification =
2266 Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, &CCC);
2267 switch (Classification.getKind()) {
2269 case Sema::NC_NonType:
2272 return true;
2273 default:
2274 break;
2275 }
2276 return false;
2277}
2278
2279/// '[' constant-expression[opt] ']'
2280///
2281Parser::TPResult Parser::TryParseBracketDeclarator() {
2282 ConsumeBracket();
2283
2284 // A constant-expression cannot begin with a '{', but the
2285 // expr-or-braced-init-list of a postfix-expression can.
2286 if (Tok.is(tok::l_brace))
2287 return TPResult::False;
2288
2289 if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch))
2290 return TPResult::Error;
2291
2292 // If we hit a comma before the ']', this is not a constant-expression,
2293 // but might still be the expr-or-braced-init-list of a postfix-expression.
2294 if (Tok.isNot(tok::r_square))
2295 return TPResult::False;
2296
2297 ConsumeBracket();
2298 return TPResult::Ambiguous;
2299}
2300
2301/// Determine whether we might be looking at the '<' template-argument-list '>'
2302/// of a template-id or simple-template-id, rather than a less-than comparison.
2303/// This will often fail and produce an ambiguity, but should never be wrong
2304/// if it returns True or False.
2305Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
2306 if (!TokensToSkip) {
2307 if (Tok.isNot(tok::less))
2308 return TPResult::False;
2309 if (NextToken().is(tok::greater))
2310 return TPResult::True;
2311 }
2312
2313 RevertingTentativeParsingAction PA(*this);
2314
2315 while (TokensToSkip) {
2317 --TokensToSkip;
2318 }
2319
2320 if (!TryConsumeToken(tok::less))
2321 return TPResult::False;
2322
2323 // We can't do much to tell an expression apart from a template-argument,
2324 // but one good distinguishing factor is that a "decl-specifier" not
2325 // followed by '(' or '{' can't appear in an expression.
2326 bool InvalidAsTemplateArgumentList = false;
2327 if (isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::False,
2328 &InvalidAsTemplateArgumentList) ==
2329 TPResult::True)
2330 return TPResult::True;
2331 if (InvalidAsTemplateArgumentList)
2332 return TPResult::False;
2333
2334 // FIXME: In many contexts, X<thing1, Type> can only be a
2335 // template-argument-list. But that's not true in general:
2336 //
2337 // using b = int;
2338 // void f() {
2339 // int a = A<B, b, c = C>D; // OK, declares b, not a template-id.
2340 //
2341 // X<Y<0, int> // ', int>' might be end of X's template argument list
2342 //
2343 // We might be able to disambiguate a few more cases if we're careful.
2344
2345 // A template-argument-list must be terminated by a '>'.
2346 if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2348 return TPResult::Ambiguous;
2349 return TPResult::False;
2350}
2351
2352/// Determine whether we might be looking at the '(' of a C++20 explicit(bool)
2353/// in an earlier language mode.
2354Parser::TPResult Parser::isExplicitBool() {
2355 assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");
2356
2357 RevertingTentativeParsingAction PA(*this);
2358 ConsumeParen();
2359
2360 // We can only have 'explicit' on a constructor, conversion function, or
2361 // deduction guide. The declarator of a deduction guide cannot be
2362 // parenthesized, so we know this isn't a deduction guide. So the only
2363 // thing we need to check for is some number of parens followed by either
2364 // the current class name or 'operator'.
2365 while (Tok.is(tok::l_paren))
2366 ConsumeParen();
2367
2369 return TPResult::Error;
2370
2371 // Class-scope constructor and conversion function names can't really be
2372 // qualified, but we get better diagnostics if we assume they can be.
2373 CXXScopeSpec SS;
2374 if (Tok.is(tok::annot_cxxscope)) {
2376 Tok.getAnnotationRange(),
2377 SS);
2378 ConsumeAnnotationToken();
2379 }
2380
2381 // 'explicit(operator' might be explicit(bool) or the declaration of a
2382 // conversion function, but it's probably a conversion function.
2383 if (Tok.is(tok::kw_operator))
2384 return TPResult::Ambiguous;
2385
2386 // If this can't be a constructor name, it can only be explicit(bool).
2387 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2388 return TPResult::True;
2389 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2390 ? *Tok.getIdentifierInfo()
2391 : *takeTemplateIdAnnotation(Tok)->Name,
2392 getCurScope(), &SS))
2393 return TPResult::True;
2394 // Formally, we must have a right-paren after the constructor name to match
2395 // the grammar for a constructor. But clang permits a parenthesized
2396 // constructor declarator, so also allow a constructor declarator to follow
2397 // with no ')' token after the constructor name.
2398 if (!NextToken().is(tok::r_paren) &&
2399 !isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(),
2400 /*DeductionGuide=*/false))
2401 return TPResult::True;
2402
2403 // Might be explicit(bool) or a parenthesized constructor name.
2404 return TPResult::Ambiguous;
2405}
static constexpr bool isOneOf()
SourceLocation Loc
Definition: SemaObjC.cpp:758
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
Definition: DeclSpec.h:210
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:95
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:213
bool isEmpty() const
No scope specifier.
Definition: DeclSpec.h:208
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
One of these records is kept for each identifier that is lexed.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
This represents a decl that may have a name.
Definition: Decl.h:249
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ParsedAttributes - A collection of parsed attributes.
Definition: ParsedAttr.h:958
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:58
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Definition: Parser.h:549
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
Definition: Parser.h:937
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
Definition: Parser.h:577
bool TryConsumeToken(tok::TokenKind Expected)
Definition: Parser.h:557
Scope * getCurScope() const
Definition: Parser.h:503
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
Definition: Parser.h:1295
const LangOptions & getLangOpts() const
Definition: Parser.h:496
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
Definition: Parser.h:1276
@ StopAtSemi
Stop skipping at semicolon.
Definition: Parser.h:1274
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
Definition: Parser.cpp:2000
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Definition: Parser.h:873
NameClassificationKind getKind() const
Definition: Sema.h:3288
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
@ NC_VarTemplate
The name was classified as a variable template name.
Definition: Sema.h:3207
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
Definition: Sema.h:3190
@ NC_FunctionTemplate
The name was classified as a function template name.
Definition: Sema.h:3209
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
Definition: Sema.h:3203
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
Definition: SemaDecl.cpp:858
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:187
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:132
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition: Token.h:99
void * getAnnotationValue() const
Definition: Token.h:234
tok::TokenKind getKind() const
Definition: Token.h:94
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
Definition: Token.h:126
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
Definition: Token.h:166
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
Definition: Token.h:101
bool isNot(tok::TokenKind K) const
Definition: Token.h:100
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
Definition: Token.h:303
Simple class containing the result of Sema::CorrectTypo.
The JSON file list parser is used to communicate input to InstallAPI.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
ImplicitTypenameContext
Definition: DeclSpec.h:1883
@ OpenCL
Definition: LangStandard.h:66
@ CPlusPlus23
Definition: LangStandard.h:61
@ CPlusPlus
Definition: LangStandard.h:56
@ CPlusPlus11
Definition: LangStandard.h:57
@ CPlusPlus17
Definition: LangStandard.h:59
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
Definition: TemplateKinds.h:30
@ TNK_Concept_template
The name refers to a concept.
Definition: TemplateKinds.h:52
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
Definition: TemplateKinds.h:50
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
Represents a complete lambda introducer.
Definition: DeclSpec.h:2832
Information about a template-id annotation token.
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.