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