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