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
15#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#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1811#include "clang/Basic/HLSLIntangibleTypes.def"
1812 if (NextToken().is(tok::l_paren))
1813 return TPResult::Ambiguous;
1814
1815 // This is a function-style cast in all cases we disambiguate other than
1816 // one:
1817 // struct S {
1818 // enum E : int { a = 4 }; // enum
1819 // enum E : int { 4 }; // bit-field
1820 // };
1821 if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
1822 return BracedCastResult;
1823
1824 if (isStartOfObjCClassMessageMissingOpenBracket())
1825 return TPResult::False;
1826
1827 return TPResult::True;
1828
1829 // GNU typeof support.
1830 case tok::kw_typeof: {
1831 if (NextToken().isNot(tok::l_paren))
1832 return TPResult::True;
1833
1834 RevertingTentativeParsingAction PA(*this);
1835
1836 TPResult TPR = TryParseTypeofSpecifier();
1837 bool isFollowedByParen = Tok.is(tok::l_paren);
1838 bool isFollowedByBrace = Tok.is(tok::l_brace);
1839
1840 if (TPR == TPResult::Error)
1841 return TPResult::Error;
1842
1843 if (isFollowedByParen)
1844 return TPResult::Ambiguous;
1845
1846 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
1847 return BracedCastResult;
1848
1849 return TPResult::True;
1850 }
1851
1852#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1853#include "clang/Basic/TransformTypeTraits.def"
1854 return TPResult::True;
1855
1856 // C11 _Alignas
1857 case tok::kw__Alignas:
1858 return TPResult::True;
1859 // C11 _Atomic
1860 case tok::kw__Atomic:
1861 return TPResult::True;
1862
1863 case tok::kw__BitInt:
1864 case tok::kw__ExtInt: {
1865 if (NextToken().isNot(tok::l_paren))
1866 return TPResult::Error;
1867 RevertingTentativeParsingAction PA(*this);
1868 ConsumeToken();
1869 ConsumeParen();
1870
1871 if (!SkipUntil(tok::r_paren, StopAtSemi))
1872 return TPResult::Error;
1873
1874 if (Tok.is(tok::l_paren))
1875 return TPResult::Ambiguous;
1876
1877 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
1878 return BracedCastResult;
1879
1880 return TPResult::True;
1881 }
1882 default:
1883 return TPResult::False;
1884 }
1885}
1886
1887bool Parser::isCXXDeclarationSpecifierAType() {
1888 switch (Tok.getKind()) {
1889 // typename-specifier
1890 case tok::annot_decltype:
1891 case tok::annot_pack_indexing_type:
1892 case tok::annot_template_id:
1893 case tok::annot_typename:
1894 case tok::kw_typeof:
1895#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1896#include "clang/Basic/TransformTypeTraits.def"
1897 return true;
1898
1899 // elaborated-type-specifier
1900 case tok::kw_class:
1901 case tok::kw_struct:
1902 case tok::kw_union:
1903 case tok::kw___interface:
1904 case tok::kw_enum:
1905 return true;
1906
1907 // simple-type-specifier
1908 case tok::kw_char:
1909 case tok::kw_wchar_t:
1910 case tok::kw_char8_t:
1911 case tok::kw_char16_t:
1912 case tok::kw_char32_t:
1913 case tok::kw_bool:
1914 case tok::kw_short:
1915 case tok::kw_int:
1916 case tok::kw__ExtInt:
1917 case tok::kw__BitInt:
1918 case tok::kw_long:
1919 case tok::kw___int64:
1920 case tok::kw___int128:
1921 case tok::kw_signed:
1922 case tok::kw_unsigned:
1923 case tok::kw_half:
1924 case tok::kw_float:
1925 case tok::kw_double:
1926 case tok::kw___bf16:
1927 case tok::kw__Float16:
1928 case tok::kw___float128:
1929 case tok::kw___ibm128:
1930 case tok::kw_void:
1931 case tok::kw___unknown_anytype:
1932 case tok::kw___auto_type:
1933 case tok::kw__Accum:
1934 case tok::kw__Fract:
1935 case tok::kw__Sat:
1936#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1937#include "clang/Basic/OpenCLImageTypes.def"
1938#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1939#include "clang/Basic/HLSLIntangibleTypes.def"
1940 return true;
1941
1942 case tok::kw_auto:
1943 return getLangOpts().CPlusPlus11;
1944
1945 case tok::kw__Atomic:
1946 // "_Atomic foo"
1947 return NextToken().is(tok::l_paren);
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954/// [GNU] typeof-specifier:
1955/// 'typeof' '(' expressions ')'
1956/// 'typeof' '(' type-name ')'
1957///
1958Parser::TPResult Parser::TryParseTypeofSpecifier() {
1959 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
1960 ConsumeToken();
1961
1962 assert(Tok.is(tok::l_paren) && "Expected '('");
1963 // Parse through the parens after 'typeof'.
1964 ConsumeParen();
1965 if (!SkipUntil(tok::r_paren, StopAtSemi))
1966 return TPResult::Error;
1967
1968 return TPResult::Ambiguous;
1969}
1970
1971/// [ObjC] protocol-qualifiers:
1972//// '<' identifier-list '>'
1973Parser::TPResult Parser::TryParseProtocolQualifiers() {
1974 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
1975 ConsumeToken();
1976 do {
1977 if (Tok.isNot(tok::identifier))
1978 return TPResult::Error;
1979 ConsumeToken();
1980
1981 if (Tok.is(tok::comma)) {
1982 ConsumeToken();
1983 continue;
1984 }
1985
1986 if (Tok.is(tok::greater)) {
1987 ConsumeToken();
1988 return TPResult::Ambiguous;
1989 }
1990 } while (false);
1991
1992 return TPResult::Error;
1993}
1994
1995/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
1996/// a constructor-style initializer, when parsing declaration statements.
1997/// Returns true for function declarator and false for constructor-style
1998/// initializer.
1999/// If during the disambiguation process a parsing error is encountered,
2000/// the function returns true to let the declaration parsing code handle it.
2001///
2002/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
2003/// exception-specification[opt]
2004///
2005bool Parser::isCXXFunctionDeclarator(
2006 bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) {
2007
2008 // C++ 8.2p1:
2009 // The ambiguity arising from the similarity between a function-style cast and
2010 // a declaration mentioned in 6.8 can also occur in the context of a
2011 // declaration. In that context, the choice is between a function declaration
2012 // with a redundant set of parentheses around a parameter name and an object
2013 // declaration with a function-style cast as the initializer. Just as for the
2014 // ambiguities mentioned in 6.8, the resolution is to consider any construct
2015 // that could possibly be a declaration a declaration.
2016
2017 RevertingTentativeParsingAction PA(*this);
2018
2019 ConsumeParen();
2020 bool InvalidAsDeclaration = false;
2021 TPResult TPR = TryParseParameterDeclarationClause(
2022 &InvalidAsDeclaration, /*VersusTemplateArgument=*/false,
2023 AllowImplicitTypename);
2024 if (TPR == TPResult::Ambiguous) {
2025 if (Tok.isNot(tok::r_paren))
2026 TPR = TPResult::False;
2027 else {
2028 const Token &Next = NextToken();
2029 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
2030 tok::kw_throw, tok::kw_noexcept, tok::l_square,
2031 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
2032 isCXX11VirtSpecifier(Next))
2033 // The next token cannot appear after a constructor-style initializer,
2034 // and can appear next in a function definition. This must be a function
2035 // declarator.
2036 TPR = TPResult::True;
2037 else if (InvalidAsDeclaration)
2038 // Use the absence of 'typename' as a tie-breaker.
2039 TPR = TPResult::False;
2040 }
2041 }
2042
2043 if (IsAmbiguous && TPR == TPResult::Ambiguous)
2044 *IsAmbiguous = true;
2045
2046 // In case of an error, let the declaration parsing code handle it.
2047 return TPR != TPResult::False;
2048}
2049
2050/// parameter-declaration-clause:
2051/// parameter-declaration-list[opt] '...'[opt]
2052/// parameter-declaration-list ',' '...'
2053///
2054/// parameter-declaration-list:
2055/// parameter-declaration
2056/// parameter-declaration-list ',' parameter-declaration
2057///
2058/// parameter-declaration:
2059/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
2060/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
2061/// '=' assignment-expression
2062/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
2063/// attributes[opt]
2064/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
2065/// attributes[opt] '=' assignment-expression
2066///
2067Parser::TPResult Parser::TryParseParameterDeclarationClause(
2068 bool *InvalidAsDeclaration, bool VersusTemplateArgument,
2069 ImplicitTypenameContext AllowImplicitTypename) {
2070
2071 if (Tok.is(tok::r_paren))
2072 return TPResult::Ambiguous;
2073
2074 // parameter-declaration-list[opt] '...'[opt]
2075 // parameter-declaration-list ',' '...'
2076 //
2077 // parameter-declaration-list:
2078 // parameter-declaration
2079 // parameter-declaration-list ',' parameter-declaration
2080 //
2081 while (true) {
2082 // '...'[opt]
2083 if (Tok.is(tok::ellipsis)) {
2084 ConsumeToken();
2085 if (Tok.is(tok::r_paren))
2086 return TPResult::True; // '...)' is a sign of a function declarator.
2087 else
2088 return TPResult::False;
2089 }
2090
2091 // An attribute-specifier-seq here is a sign of a function declarator.
2092 if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
2093 /*OuterMightBeMessageSend*/true))
2094 return TPResult::True;
2095
2096 ParsedAttributes attrs(AttrFactory);
2097 MaybeParseMicrosoftAttributes(attrs);
2098
2099 // decl-specifier-seq
2100 // A parameter-declaration's initializer must be preceded by an '=', so
2101 // decl-specifier-seq '{' is not a parameter in C++11.
2102 TPResult TPR = isCXXDeclarationSpecifier(
2103 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2104 // A declaration-specifier (not followed by '(' or '{') means this can't be
2105 // an expression, but it could still be a template argument.
2106 if (TPR != TPResult::Ambiguous &&
2107 !(VersusTemplateArgument && TPR == TPResult::True))
2108 return TPR;
2109
2110 bool SeenType = false;
2111 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
2112 do {
2113 SeenType |= isCXXDeclarationSpecifierAType();
2114 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2115 return TPResult::Error;
2116
2117 // If we see a parameter name, this can't be a template argument.
2118 if (SeenType && Tok.is(tok::identifier))
2119 return TPResult::True;
2120
2121 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2122 InvalidAsDeclaration);
2123 if (TPR == TPResult::Error)
2124 return TPR;
2125
2126 // Two declaration-specifiers means this can't be an expression.
2127 if (TPR == TPResult::True && !VersusTemplateArgument)
2128 return TPR;
2129 } while (TPR != TPResult::False);
2130
2131 // declarator
2132 // abstract-declarator[opt]
2133 TPR = TryParseDeclarator(
2134 /*mayBeAbstract=*/true,
2135 /*mayHaveIdentifier=*/true,
2136 /*mayHaveDirectInit=*/false,
2137 /*mayHaveTrailingReturnType=*/DeclarationSpecifierIsAuto);
2138 if (TPR != TPResult::Ambiguous)
2139 return TPR;
2140
2141 // [GNU] attributes[opt]
2142 if (Tok.is(tok::kw___attribute))
2143 return TPResult::True;
2144
2145 // If we're disambiguating a template argument in a default argument in
2146 // a class definition versus a parameter declaration, an '=' here
2147 // disambiguates the parse one way or the other.
2148 // If this is a parameter, it must have a default argument because
2149 // (a) the previous parameter did, and
2150 // (b) this must be the first declaration of the function, so we can't
2151 // inherit any default arguments from elsewhere.
2152 // FIXME: If we reach a ')' without consuming any '>'s, then this must
2153 // also be a function parameter (that's missing its default argument).
2154 if (VersusTemplateArgument)
2155 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
2156
2157 if (Tok.is(tok::equal)) {
2158 // '=' assignment-expression
2159 // Parse through assignment-expression.
2160 if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
2161 return TPResult::Error;
2162 }
2163
2164 if (Tok.is(tok::ellipsis)) {
2165 ConsumeToken();
2166 if (Tok.is(tok::r_paren))
2167 return TPResult::True; // '...)' is a sign of a function declarator.
2168 else
2169 return TPResult::False;
2170 }
2171
2172 if (!TryConsumeToken(tok::comma))
2173 break;
2174 }
2175
2176 return TPResult::Ambiguous;
2177}
2178
2179/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
2180/// parsing as a function declarator.
2181/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
2182/// return TPResult::Ambiguous, otherwise it will return either False() or
2183/// Error().
2184///
2185/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
2186/// exception-specification[opt]
2187///
2188/// exception-specification:
2189/// 'throw' '(' type-id-list[opt] ')'
2190///
2191Parser::TPResult
2192Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
2193 // The '(' is already parsed.
2194
2195 TPResult TPR = TryParseParameterDeclarationClause();
2196 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
2197 TPR = TPResult::False;
2198
2199 if (TPR == TPResult::False || TPR == TPResult::Error)
2200 return TPR;
2201
2202 // Parse through the parens.
2203 if (!SkipUntil(tok::r_paren, StopAtSemi))
2204 return TPResult::Error;
2205
2206 // cv-qualifier-seq
2207 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2208 tok::kw_restrict))
2209 ConsumeToken();
2210
2211 // ref-qualifier[opt]
2212 if (Tok.isOneOf(tok::amp, tok::ampamp))
2213 ConsumeToken();
2214
2215 // exception-specification
2216 if (Tok.is(tok::kw_throw)) {
2217 ConsumeToken();
2218 if (Tok.isNot(tok::l_paren))
2219 return TPResult::Error;
2220
2221 // Parse through the parens after 'throw'.
2222 ConsumeParen();
2223 if (!SkipUntil(tok::r_paren, StopAtSemi))
2224 return TPResult::Error;
2225 }
2226 if (Tok.is(tok::kw_noexcept)) {
2227 ConsumeToken();
2228 // Possibly an expression as well.
2229 if (Tok.is(tok::l_paren)) {
2230 // Find the matching rparen.
2231 ConsumeParen();
2232 if (!SkipUntil(tok::r_paren, StopAtSemi))
2233 return TPResult::Error;
2234 }
2235 }
2236
2237 // attribute-specifier-seq
2238 if (!TrySkipAttributes())
2239 return TPResult::Ambiguous;
2240
2241 // trailing-return-type
2242 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
2243 if (TPR == TPResult::True)
2244 return TPR;
2245 ConsumeToken();
2246 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
2247 return TPResult::False;
2248 }
2249 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2250 return TPResult::True;
2251 }
2252
2253 return TPResult::Ambiguous;
2254}
2255
2256// When parsing an identifier after an arrow it may be a member expression,
2257// in which case we should not annotate it as an independant expression
2258// so we just lookup that name, if it's not a type the construct is not
2259// a function declaration.
2260bool Parser::NameAfterArrowIsNonType() {
2261 assert(Tok.is(tok::identifier));
2262 Token Next = NextToken();
2263 if (Next.is(tok::coloncolon))
2264 return false;
2265 IdentifierInfo *Name = Tok.getIdentifierInfo();
2266 SourceLocation NameLoc = Tok.getLocation();
2267 CXXScopeSpec SS;
2268 TentativeParseCCC CCC(Next);
2269 Sema::NameClassification Classification =
2270 Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, &CCC);
2271 switch (Classification.getKind()) {
2273 case Sema::NC_NonType:
2276 return true;
2277 default:
2278 break;
2279 }
2280 return false;
2281}
2282
2283/// '[' constant-expression[opt] ']'
2284///
2285Parser::TPResult Parser::TryParseBracketDeclarator() {
2286 ConsumeBracket();
2287
2288 // A constant-expression cannot begin with a '{', but the
2289 // expr-or-braced-init-list of a postfix-expression can.
2290 if (Tok.is(tok::l_brace))
2291 return TPResult::False;
2292
2293 if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch))
2294 return TPResult::Error;
2295
2296 // If we hit a comma before the ']', this is not a constant-expression,
2297 // but might still be the expr-or-braced-init-list of a postfix-expression.
2298 if (Tok.isNot(tok::r_square))
2299 return TPResult::False;
2300
2301 ConsumeBracket();
2302 return TPResult::Ambiguous;
2303}
2304
2305/// Determine whether we might be looking at the '<' template-argument-list '>'
2306/// of a template-id or simple-template-id, rather than a less-than comparison.
2307/// This will often fail and produce an ambiguity, but should never be wrong
2308/// if it returns True or False.
2309Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
2310 if (!TokensToSkip) {
2311 if (Tok.isNot(tok::less))
2312 return TPResult::False;
2313 if (NextToken().is(tok::greater))
2314 return TPResult::True;
2315 }
2316
2317 RevertingTentativeParsingAction PA(*this);
2318
2319 while (TokensToSkip) {
2321 --TokensToSkip;
2322 }
2323
2324 if (!TryConsumeToken(tok::less))
2325 return TPResult::False;
2326
2327 // We can't do much to tell an expression apart from a template-argument,
2328 // but one good distinguishing factor is that a "decl-specifier" not
2329 // followed by '(' or '{' can't appear in an expression.
2330 bool InvalidAsTemplateArgumentList = false;
2331 if (isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::False,
2332 &InvalidAsTemplateArgumentList) ==
2333 TPResult::True)
2334 return TPResult::True;
2335 if (InvalidAsTemplateArgumentList)
2336 return TPResult::False;
2337
2338 // FIXME: In many contexts, X<thing1, Type> can only be a
2339 // template-argument-list. But that's not true in general:
2340 //
2341 // using b = int;
2342 // void f() {
2343 // int a = A<B, b, c = C>D; // OK, declares b, not a template-id.
2344 //
2345 // X<Y<0, int> // ', int>' might be end of X's template argument list
2346 //
2347 // We might be able to disambiguate a few more cases if we're careful.
2348
2349 // A template-argument-list must be terminated by a '>'.
2350 if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2352 return TPResult::Ambiguous;
2353 return TPResult::False;
2354}
2355
2356/// Determine whether we might be looking at the '(' of a C++20 explicit(bool)
2357/// in an earlier language mode.
2358Parser::TPResult Parser::isExplicitBool() {
2359 assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");
2360
2361 RevertingTentativeParsingAction PA(*this);
2362 ConsumeParen();
2363
2364 // We can only have 'explicit' on a constructor, conversion function, or
2365 // deduction guide. The declarator of a deduction guide cannot be
2366 // parenthesized, so we know this isn't a deduction guide. So the only
2367 // thing we need to check for is some number of parens followed by either
2368 // the current class name or 'operator'.
2369 while (Tok.is(tok::l_paren))
2370 ConsumeParen();
2371
2373 return TPResult::Error;
2374
2375 // Class-scope constructor and conversion function names can't really be
2376 // qualified, but we get better diagnostics if we assume they can be.
2377 CXXScopeSpec SS;
2378 if (Tok.is(tok::annot_cxxscope)) {
2380 Tok.getAnnotationRange(),
2381 SS);
2382 ConsumeAnnotationToken();
2383 }
2384
2385 // 'explicit(operator' might be explicit(bool) or the declaration of a
2386 // conversion function, but it's probably a conversion function.
2387 if (Tok.is(tok::kw_operator))
2388 return TPResult::Ambiguous;
2389
2390 // If this can't be a constructor name, it can only be explicit(bool).
2391 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2392 return TPResult::True;
2393 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2394 ? *Tok.getIdentifierInfo()
2395 : *takeTemplateIdAnnotation(Tok)->Name,
2396 getCurScope(), &SS))
2397 return TPResult::True;
2398 // Formally, we must have a right-paren after the constructor name to match
2399 // the grammar for a constructor. But clang permits a parenthesized
2400 // constructor declarator, so also allow a constructor declarator to follow
2401 // with no ')' token after the constructor name.
2402 if (!NextToken().is(tok::r_paren) &&
2403 !isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(),
2404 /*DeductionGuide=*/false))
2405 return TPResult::True;
2406
2407 // Might be explicit(bool) or a parenthesized constructor name.
2408 return TPResult::Ambiguous;
2409}
static constexpr bool isOneOf()
SourceLocation Loc
Definition: SemaObjC.cpp:759
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:253
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ParsedAttributes - A collection of parsed attributes.
Definition: ParsedAttr.h:956
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:548
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
Definition: Parser.h:936
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
Definition: Parser.h:576
bool TryConsumeToken(tok::TokenKind Expected)
Definition: Parser.h:556
Scope * getCurScope() const
Definition: Parser.h:502
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:1294
const LangOptions & getLangOpts() const
Definition: Parser.h:495
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
Definition: Parser.h:1275
@ StopAtSemi
Stop skipping at semicolon.
Definition: Parser.h:1273
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
Definition: Parser.cpp:1995
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Definition: Parser.h:872
NameClassificationKind getKind() const
Definition: Sema.h:3281
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:3200
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
Definition: Sema.h:3183
@ NC_FunctionTemplate
The name was classified as a function template name.
Definition: Sema.h:3202
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
Definition: Sema.h:3196
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:860
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:1886
@ OpenCL
Definition: LangStandard.h:65
@ CPlusPlus23
Definition: LangStandard.h:60
@ CPlusPlus
Definition: LangStandard.h:55
@ CPlusPlus11
Definition: LangStandard.h:56
@ CPlusPlus17
Definition: LangStandard.h:58
@ 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:2835
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.