1//===--- ParseExprCXX.cpp - C++ Expression 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 Expression parsing implementation for C++.
10//
11//===----------------------------------------------------------------------===//
12#include "clang/AST/ASTContext.h"
13#include "clang/AST/Decl.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/ExprCXX.h"
16#include "clang/Basic/DiagnosticParse.h"
17#include "clang/Basic/PrettyStackTrace.h"
18#include "clang/Basic/TemplateKinds.h"
19#include "clang/Basic/TokenKinds.h"
20#include "clang/Lex/LiteralSupport.h"
21#include "clang/Parse/Parser.h"
22#include "clang/Parse/RAIIObjectsForParser.h"
23#include "clang/Sema/DeclSpec.h"
24#include "clang/Sema/EnterExpressionEvaluationContext.h"
25#include "clang/Sema/ParsedTemplate.h"
26#include "clang/Sema/Scope.h"
27#include "clang/Sema/SemaCodeCompletion.h"
28#include "llvm/Support/Compiler.h"
29#include "llvm/Support/ErrorHandling.h"
30#include <numeric>
31
32using namespace clang;
33
34static int SelectDigraphErrorMessage(tok::TokenKind Kind) {
35 switch (Kind) {
36 // template name
37 case tok::unknown: return 0;
38 // casts
39 case tok::kw_addrspace_cast: return 1;
40 case tok::kw_const_cast: return 2;
41 case tok::kw_dynamic_cast: return 3;
42 case tok::kw_reinterpret_cast: return 4;
43 case tok::kw_static_cast: return 5;
44 default:
45 llvm_unreachable("Unknown type for digraph error message.");
46 }
47}
48
49bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {
50 SourceManager &SM = PP.getSourceManager();
51 SourceLocation FirstLoc = SM.getSpellingLoc(Loc: First.getLocation());
52 SourceLocation FirstEnd = FirstLoc.getLocWithOffset(Offset: First.getLength());
53 return FirstEnd == SM.getSpellingLoc(Loc: Second.getLocation());
54}
55
56// Suggest fixit for "<::" after a cast.
57static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken,
58 Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) {
59 // Pull '<:' and ':' off token stream.
60 if (!AtDigraph)
61 PP.Lex(Result&: DigraphToken);
62 PP.Lex(Result&: ColonToken);
63
64 SourceRange Range;
65 Range.setBegin(DigraphToken.getLocation());
66 Range.setEnd(ColonToken.getLocation());
67 P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)
68 << SelectDigraphErrorMessage(Kind)
69 << FixItHint::CreateReplacement(Range, "< ::");
70
71 // Update token information to reflect their change in token type.
72 ColonToken.setKind(tok::coloncolon);
73 ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(Offset: -1));
74 ColonToken.setLength(2);
75 DigraphToken.setKind(tok::less);
76 DigraphToken.setLength(1);
77
78 // Push new tokens back to token stream.
79 PP.EnterToken(Tok: ColonToken, /*IsReinject*/ true);
80 if (!AtDigraph)
81 PP.EnterToken(Tok: DigraphToken, /*IsReinject*/ true);
82}
83
84void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
85 bool EnteringContext,
86 IdentifierInfo &II, CXXScopeSpec &SS) {
87 if (!Next.is(K: tok::l_square) || Next.getLength() != 2)
88 return;
89
90 Token SecondToken = GetLookAheadToken(N: 2);
91 if (!SecondToken.is(K: tok::colon) || !areTokensAdjacent(First: Next, Second: SecondToken))
92 return;
93
94 TemplateTy Template;
95 UnqualifiedId TemplateName;
96 TemplateName.setIdentifier(Id: &II, IdLoc: Tok.getLocation());
97 bool MemberOfUnknownSpecialization;
98 if (!Actions.isTemplateName(S: getCurScope(), SS, /*hasTemplateKeyword=*/false,
99 Name: TemplateName, ObjectType, EnteringContext,
100 Template, MemberOfUnknownSpecialization))
101 return;
102
103 FixDigraph(P&: *this, PP, DigraphToken&: Next, ColonToken&: SecondToken, Kind: tok::unknown,
104 /*AtDigraph*/false);
105}
106
107bool Parser::ParseOptionalCXXScopeSpecifier(
108 CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,
109 bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename,
110 const IdentifierInfo **LastII, bool OnlyNamespace, bool InUsingDeclaration,
111 bool Disambiguation) {
112 assert(getLangOpts().CPlusPlus &&
113 "Call sites of this function should be guarded by checking for C++");
114
115 if (Tok.is(K: tok::annot_cxxscope)) {
116 assert(!LastII && "want last identifier but have already annotated scope");
117 assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");
118 Actions.RestoreNestedNameSpecifierAnnotation(Annotation: Tok.getAnnotationValue(),
119 AnnotationRange: Tok.getAnnotationRange(),
120 SS);
121 ConsumeAnnotationToken();
122 return false;
123 }
124
125 // Has to happen before any "return false"s in this function.
126 bool CheckForDestructor = false;
127 if (MayBePseudoDestructor && *MayBePseudoDestructor) {
128 CheckForDestructor = true;
129 *MayBePseudoDestructor = false;
130 }
131
132 if (LastII)
133 *LastII = nullptr;
134
135 bool HasScopeSpecifier = false;
136
137 if (Tok.is(K: tok::coloncolon)) {
138 // ::new and ::delete aren't nested-name-specifiers.
139 tok::TokenKind NextKind = NextToken().getKind();
140 if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
141 return false;
142
143 if (NextKind == tok::l_brace) {
144 // It is invalid to have :: {, consume the scope qualifier and pretend
145 // like we never saw it.
146 Diag(ConsumeToken(), diag::err_expected) << tok::identifier;
147 } else {
148 // '::' - Global scope qualifier.
149 if (Actions.ActOnCXXGlobalScopeSpecifier(CCLoc: ConsumeToken(), SS))
150 return true;
151
152 HasScopeSpecifier = true;
153 }
154 }
155
156 if (Tok.is(K: tok::kw___super)) {
157 SourceLocation SuperLoc = ConsumeToken();
158 if (!Tok.is(K: tok::coloncolon)) {
159 Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);
160 return true;
161 }
162
163 return Actions.ActOnSuperScopeSpecifier(SuperLoc, ColonColonLoc: ConsumeToken(), SS);
164 }
165
166 if (!HasScopeSpecifier &&
167 Tok.isOneOf(K1: tok::kw_decltype, K2: tok::annot_decltype)) {
168 DeclSpec DS(AttrFactory);
169 SourceLocation DeclLoc = Tok.getLocation();
170 SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
171
172 SourceLocation CCLoc;
173 // Work around a standard defect: 'decltype(auto)::' is not a
174 // nested-name-specifier.
175 if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto ||
176 !TryConsumeToken(Expected: tok::coloncolon, Loc&: CCLoc)) {
177 AnnotateExistingDecltypeSpecifier(DS, StartLoc: DeclLoc, EndLoc);
178 return false;
179 }
180
181 if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, ColonColonLoc: CCLoc))
182 SS.SetInvalid(SourceRange(DeclLoc, CCLoc));
183
184 HasScopeSpecifier = true;
185 }
186
187 else if (!HasScopeSpecifier && Tok.is(K: tok::identifier) &&
188 GetLookAheadToken(N: 1).is(K: tok::ellipsis) &&
189 GetLookAheadToken(N: 2).is(K: tok::l_square) &&
190 !GetLookAheadToken(N: 3).is(K: tok::r_square)) {
191 SourceLocation Start = Tok.getLocation();
192 DeclSpec DS(AttrFactory);
193 SourceLocation CCLoc;
194 SourceLocation EndLoc = ParsePackIndexingType(DS);
195 if (DS.getTypeSpecType() == DeclSpec::TST_error)
196 return false;
197
198 QualType Type = Actions.ActOnPackIndexingType(
199 Pattern: DS.getRepAsType().get(), IndexExpr: DS.getPackIndexingExpr(), Loc: DS.getBeginLoc(),
200 EllipsisLoc: DS.getEllipsisLoc());
201
202 if (Type.isNull())
203 return false;
204
205 // C++ [cpp23.dcl.dcl-2]:
206 // Previously, T...[n] would declare a pack of function parameters.
207 // T...[n] is now a pack-index-specifier. [...] Valid C++ 2023 code that
208 // declares a pack of parameters without specifying a declarator-id
209 // becomes ill-formed.
210 //
211 // However, we still treat it as a pack indexing type because the use case
212 // is fairly rare, to ensure semantic consistency given that we have
213 // backported this feature to pre-C++26 modes.
214 if (!Tok.is(tok::coloncolon) && !getLangOpts().CPlusPlus26 &&
215 getCurScope()->isFunctionDeclarationScope())
216 Diag(Start, diag::warn_pre_cxx26_ambiguous_pack_indexing_type) << Type;
217
218 if (!TryConsumeToken(Expected: tok::coloncolon, Loc&: CCLoc)) {
219 AnnotateExistingIndexedTypeNamePack(T: ParsedType::make(P: Type), StartLoc: Start,
220 EndLoc);
221 return false;
222 }
223 if (Actions.ActOnCXXNestedNameSpecifierIndexedPack(SS, DS, ColonColonLoc: CCLoc,
224 Type: std::move(Type)))
225 SS.SetInvalid(SourceRange(Start, CCLoc));
226 HasScopeSpecifier = true;
227 }
228
229 // Preferred type might change when parsing qualifiers, we need the original.
230 auto SavedType = PreferredType;
231 while (true) {
232 if (HasScopeSpecifier) {
233 if (Tok.is(K: tok::code_completion)) {
234 cutOffParsing();
235 // Code completion for a nested-name-specifier, where the code
236 // completion token follows the '::'.
237 Actions.CodeCompletion().CodeCompleteQualifiedId(
238 S: getCurScope(), SS, EnteringContext, IsUsingDeclaration: InUsingDeclaration,
239 BaseType: ObjectType.get(), PreferredType: SavedType.get(SS.getBeginLoc()));
240 // Include code completion token into the range of the scope otherwise
241 // when we try to annotate the scope tokens the dangling code completion
242 // token will cause assertion in
243 // Preprocessor::AnnotatePreviousCachedTokens.
244 SS.setEndLoc(Tok.getLocation());
245 return true;
246 }
247
248 // C++ [basic.lookup.classref]p5:
249 // If the qualified-id has the form
250 //
251 // ::class-name-or-namespace-name::...
252 //
253 // the class-name-or-namespace-name is looked up in global scope as a
254 // class-name or namespace-name.
255 //
256 // To implement this, we clear out the object type as soon as we've
257 // seen a leading '::' or part of a nested-name-specifier.
258 ObjectType = nullptr;
259 }
260
261 // nested-name-specifier:
262 // nested-name-specifier 'template'[opt] simple-template-id '::'
263
264 // Parse the optional 'template' keyword, then make sure we have
265 // 'identifier <' after it.
266 if (Tok.is(K: tok::kw_template)) {
267 // If we don't have a scope specifier or an object type, this isn't a
268 // nested-name-specifier, since they aren't allowed to start with
269 // 'template'.
270 if (!HasScopeSpecifier && !ObjectType)
271 break;
272
273 TentativeParsingAction TPA(*this);
274 SourceLocation TemplateKWLoc = ConsumeToken();
275
276 UnqualifiedId TemplateName;
277 if (Tok.is(K: tok::identifier)) {
278 // Consume the identifier.
279 TemplateName.setIdentifier(Id: Tok.getIdentifierInfo(), IdLoc: Tok.getLocation());
280 ConsumeToken();
281 } else if (Tok.is(K: tok::kw_operator)) {
282 // We don't need to actually parse the unqualified-id in this case,
283 // because a simple-template-id cannot start with 'operator', but
284 // go ahead and parse it anyway for consistency with the case where
285 // we already annotated the template-id.
286 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
287 Result&: TemplateName)) {
288 TPA.Commit();
289 break;
290 }
291
292 if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId &&
293 TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) {
294 Diag(TemplateName.getSourceRange().getBegin(),
295 diag::err_id_after_template_in_nested_name_spec)
296 << TemplateName.getSourceRange();
297 TPA.Commit();
298 break;
299 }
300 } else {
301 TPA.Revert();
302 break;
303 }
304
305 // If the next token is not '<', we have a qualified-id that refers
306 // to a template name, such as T::template apply, but is not a
307 // template-id.
308 if (Tok.isNot(K: tok::less)) {
309 TPA.Revert();
310 break;
311 }
312
313 // Commit to parsing the template-id.
314 TPA.Commit();
315 TemplateTy Template;
316 TemplateNameKind TNK = Actions.ActOnTemplateName(
317 S: getCurScope(), SS, TemplateKWLoc, Name: TemplateName, ObjectType,
318 EnteringContext, Template, /*AllowInjectedClassName*/ true);
319 if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,
320 TemplateName, AllowTypeAnnotation: false))
321 return true;
322
323 continue;
324 }
325
326 if (Tok.is(K: tok::annot_template_id) && NextToken().is(K: tok::coloncolon)) {
327 // We have
328 //
329 // template-id '::'
330 //
331 // So we need to check whether the template-id is a simple-template-id of
332 // the right kind (it should name a type or be dependent), and then
333 // convert it into a type within the nested-name-specifier.
334 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok);
335 if (CheckForDestructor && GetLookAheadToken(N: 2).is(K: tok::tilde)) {
336 *MayBePseudoDestructor = true;
337 return false;
338 }
339
340 if (LastII)
341 *LastII = TemplateId->Name;
342
343 // Consume the template-id token.
344 ConsumeAnnotationToken();
345
346 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
347 SourceLocation CCLoc = ConsumeToken();
348
349 HasScopeSpecifier = true;
350
351 ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
352 TemplateId->NumArgs);
353
354 if (TemplateId->isInvalid() ||
355 Actions.ActOnCXXNestedNameSpecifier(S: getCurScope(),
356 SS,
357 TemplateKWLoc: TemplateId->TemplateKWLoc,
358 TemplateName: TemplateId->Template,
359 TemplateNameLoc: TemplateId->TemplateNameLoc,
360 LAngleLoc: TemplateId->LAngleLoc,
361 TemplateArgs: TemplateArgsPtr,
362 RAngleLoc: TemplateId->RAngleLoc,
363 CCLoc,
364 EnteringContext)) {
365 SourceLocation StartLoc
366 = SS.getBeginLoc().isValid()? SS.getBeginLoc()
367 : TemplateId->TemplateNameLoc;
368 SS.SetInvalid(SourceRange(StartLoc, CCLoc));
369 }
370
371 continue;
372 }
373
374 switch (Tok.getKind()) {
375#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
376#include "clang/Basic/TransformTypeTraits.def"
377 if (!NextToken().is(K: tok::l_paren)) {
378 Tok.setKind(tok::identifier);
379 Diag(Tok, diag::ext_keyword_as_ident)
380 << Tok.getIdentifierInfo()->getName() << 0;
381 continue;
382 }
383 [[fallthrough]];
384 default:
385 break;
386 }
387
388 // The rest of the nested-name-specifier possibilities start with
389 // tok::identifier.
390 if (Tok.isNot(K: tok::identifier))
391 break;
392
393 IdentifierInfo &II = *Tok.getIdentifierInfo();
394
395 // nested-name-specifier:
396 // type-name '::'
397 // namespace-name '::'
398 // nested-name-specifier identifier '::'
399 Token Next = NextToken();
400 Sema::NestedNameSpecInfo IdInfo(&II, Tok.getLocation(), Next.getLocation(),
401 ObjectType);
402
403 // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover
404 // and emit a fixit hint for it.
405 if (Next.is(K: tok::colon) && !ColonIsSacred) {
406 if (Actions.IsInvalidUnlessNestedName(S: getCurScope(), SS, IdInfo,
407 EnteringContext) &&
408 // If the token after the colon isn't an identifier, it's still an
409 // error, but they probably meant something else strange so don't
410 // recover like this.
411 PP.LookAhead(N: 1).is(K: tok::identifier)) {
412 Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)
413 << FixItHint::CreateReplacement(Next.getLocation(), "::");
414 // Recover as if the user wrote '::'.
415 Next.setKind(tok::coloncolon);
416 }
417 }
418
419 if (Next.is(K: tok::coloncolon) && GetLookAheadToken(N: 2).is(K: tok::l_brace)) {
420 // It is invalid to have :: {, consume the scope qualifier and pretend
421 // like we never saw it.
422 Token Identifier = Tok; // Stash away the identifier.
423 ConsumeToken(); // Eat the identifier, current token is now '::'.
424 ConsumeToken();
425 Diag(getEndOfPreviousToken(), diag::err_expected) << tok::identifier;
426 UnconsumeToken(Consumed&: Identifier); // Stick the identifier back.
427 Next = NextToken(); // Point Next at the '{' token.
428 }
429
430 if (Next.is(K: tok::coloncolon)) {
431 if (CheckForDestructor && GetLookAheadToken(N: 2).is(K: tok::tilde)) {
432 *MayBePseudoDestructor = true;
433 return false;
434 }
435
436 if (ColonIsSacred) {
437 const Token &Next2 = GetLookAheadToken(N: 2);
438 if (Next2.is(K: tok::kw_private) || Next2.is(K: tok::kw_protected) ||
439 Next2.is(K: tok::kw_public) || Next2.is(K: tok::kw_virtual)) {
440 Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)
441 << Next2.getName()
442 << FixItHint::CreateReplacement(Next.getLocation(), ":");
443 Token ColonColon;
444 PP.Lex(Result&: ColonColon);
445 ColonColon.setKind(tok::colon);
446 PP.EnterToken(Tok: ColonColon, /*IsReinject*/ true);
447 break;
448 }
449 }
450
451 if (LastII)
452 *LastII = &II;
453
454 // We have an identifier followed by a '::'. Lookup this name
455 // as the name in a nested-name-specifier.
456 Token Identifier = Tok;
457 SourceLocation IdLoc = ConsumeToken();
458 assert(Tok.isOneOf(tok::coloncolon, tok::colon) &&
459 "NextToken() not working properly!");
460 Token ColonColon = Tok;
461 SourceLocation CCLoc = ConsumeToken();
462
463 bool IsCorrectedToColon = false;
464 bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
465 if (Actions.ActOnCXXNestedNameSpecifier(
466 S: getCurScope(), IdInfo, EnteringContext, SS, IsCorrectedToColon: CorrectionFlagPtr,
467 OnlyNamespace)) {
468 // Identifier is not recognized as a nested name, but we can have
469 // mistyped '::' instead of ':'.
470 if (CorrectionFlagPtr && IsCorrectedToColon) {
471 ColonColon.setKind(tok::colon);
472 PP.EnterToken(Tok, /*IsReinject*/ true);
473 PP.EnterToken(Tok: ColonColon, /*IsReinject*/ true);
474 Tok = Identifier;
475 break;
476 }
477 SS.SetInvalid(SourceRange(IdLoc, CCLoc));
478 }
479 HasScopeSpecifier = true;
480 continue;
481 }
482
483 CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);
484
485 // nested-name-specifier:
486 // type-name '<'
487 if (Next.is(K: tok::less)) {
488
489 TemplateTy Template;
490 UnqualifiedId TemplateName;
491 TemplateName.setIdentifier(Id: &II, IdLoc: Tok.getLocation());
492 bool MemberOfUnknownSpecialization;
493 if (TemplateNameKind TNK = Actions.isTemplateName(
494 S: getCurScope(), SS,
495 /*hasTemplateKeyword=*/false, Name: TemplateName, ObjectType,
496 EnteringContext, Template, MemberOfUnknownSpecialization,
497 Disambiguation)) {
498 // If lookup didn't find anything, we treat the name as a template-name
499 // anyway. C++20 requires this, and in prior language modes it improves
500 // error recovery. But before we commit to this, check that we actually
501 // have something that looks like a template-argument-list next.
502 if (!IsTypename && TNK == TNK_Undeclared_template &&
503 isTemplateArgumentList(TokensToSkip: 1) == TPResult::False)
504 break;
505
506 // We have found a template name, so annotate this token
507 // with a template-id annotation. We do not permit the
508 // template-id to be translated into a type annotation,
509 // because some clients (e.g., the parsing of class template
510 // specializations) still want to see the original template-id
511 // token, and it might not be a type at all (e.g. a concept name in a
512 // type-constraint).
513 ConsumeToken();
514 if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc: SourceLocation(),
515 TemplateName, AllowTypeAnnotation: false))
516 return true;
517 continue;
518 }
519
520 if (MemberOfUnknownSpecialization && !Disambiguation &&
521 (ObjectType || SS.isSet()) &&
522 (IsTypename || isTemplateArgumentList(TokensToSkip: 1) == TPResult::True)) {
523 // If we had errors before, ObjectType can be dependent even without any
524 // templates. Do not report missing template keyword in that case.
525 if (!ObjectHadErrors) {
526 // We have something like t::getAs<T>, where getAs is a
527 // member of an unknown specialization. However, this will only
528 // parse correctly as a template, so suggest the keyword 'template'
529 // before 'getAs' and treat this as a dependent template name.
530 unsigned DiagID = diag::err_missing_dependent_template_keyword;
531 if (getLangOpts().MicrosoftExt)
532 DiagID = diag::warn_missing_dependent_template_keyword;
533
534 Diag(Loc: Tok.getLocation(), DiagID)
535 << II.getName()
536 << FixItHint::CreateInsertion(InsertionLoc: Tok.getLocation(), Code: "template ");
537 }
538 ConsumeToken();
539
540 TemplateNameKind TNK = Actions.ActOnTemplateName(
541 S: getCurScope(), SS, /*TemplateKWLoc=*/SourceLocation(), Name: TemplateName,
542 ObjectType, EnteringContext, Template,
543 /*AllowInjectedClassName=*/true);
544 if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc: SourceLocation(),
545 TemplateName, AllowTypeAnnotation: false))
546 return true;
547
548 continue;
549 }
550 }
551
552 // We don't have any tokens that form the beginning of a
553 // nested-name-specifier, so we're done.
554 break;
555 }
556
557 // Even if we didn't see any pieces of a nested-name-specifier, we
558 // still check whether there is a tilde in this position, which
559 // indicates a potential pseudo-destructor.
560 if (CheckForDestructor && !HasScopeSpecifier && Tok.is(K: tok::tilde))
561 *MayBePseudoDestructor = true;
562
563 return false;
564}
565
566ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS,
567 bool isAddressOfOperand,
568 Token &Replacement) {
569 ExprResult E;
570
571 // We may have already annotated this id-expression.
572 switch (Tok.getKind()) {
573 case tok::annot_non_type: {
574 NamedDecl *ND = getNonTypeAnnotation(Tok);
575 SourceLocation Loc = ConsumeAnnotationToken();
576 E = Actions.ActOnNameClassifiedAsNonType(S: getCurScope(), SS, Found: ND, NameLoc: Loc, NextToken: Tok);
577 break;
578 }
579
580 case tok::annot_non_type_dependent: {
581 IdentifierInfo *II = getIdentifierAnnotation(Tok);
582 SourceLocation Loc = ConsumeAnnotationToken();
583
584 // This is only the direct operand of an & operator if it is not
585 // followed by a postfix-expression suffix.
586 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
587 isAddressOfOperand = false;
588
589 E = Actions.ActOnNameClassifiedAsDependentNonType(SS, Name: II, NameLoc: Loc,
590 IsAddressOfOperand: isAddressOfOperand);
591 break;
592 }
593
594 case tok::annot_non_type_undeclared: {
595 assert(SS.isEmpty() &&
596 "undeclared non-type annotation should be unqualified");
597 IdentifierInfo *II = getIdentifierAnnotation(Tok);
598 SourceLocation Loc = ConsumeAnnotationToken();
599 E = Actions.ActOnNameClassifiedAsUndeclaredNonType(Name: II, NameLoc: Loc);
600 break;
601 }
602
603 default:
604 SourceLocation TemplateKWLoc;
605 UnqualifiedId Name;
606 if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
607 /*ObjectHadErrors=*/false,
608 /*EnteringContext=*/false,
609 /*AllowDestructorName=*/false,
610 /*AllowConstructorName=*/false,
611 /*AllowDeductionGuide=*/false, TemplateKWLoc: &TemplateKWLoc, Result&: Name))
612 return ExprError();
613
614 // This is only the direct operand of an & operator if it is not
615 // followed by a postfix-expression suffix.
616 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
617 isAddressOfOperand = false;
618
619 E = Actions.ActOnIdExpression(
620 S: getCurScope(), SS, TemplateKWLoc, Id&: Name, HasTrailingLParen: Tok.is(K: tok::l_paren),
621 IsAddressOfOperand: isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false,
622 KeywordReplacement: &Replacement);
623 break;
624 }
625
626 // Might be a pack index expression!
627 E = tryParseCXXPackIndexingExpression(PackIdExpression: E);
628
629 if (!E.isInvalid() && !E.isUnset() && Tok.is(K: tok::less))
630 checkPotentialAngleBracket(PotentialTemplateName&: E);
631 return E;
632}
633
634ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) {
635 assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) &&
636 "expected ...[");
637 SourceLocation EllipsisLoc = ConsumeToken();
638 BalancedDelimiterTracker T(*this, tok::l_square);
639 T.consumeOpen();
640 ExprResult IndexExpr = ParseConstantExpression();
641 if (T.consumeClose() || IndexExpr.isInvalid())
642 return ExprError();
643 return Actions.ActOnPackIndexingExpr(S: getCurScope(), PackExpression: PackIdExpression.get(),
644 EllipsisLoc, LSquareLoc: T.getOpenLocation(),
645 IndexExpr: IndexExpr.get(), RSquareLoc: T.getCloseLocation());
646}
647
648ExprResult
649Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) {
650 ExprResult E = PackIdExpression;
651 if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() &&
652 Tok.is(K: tok::ellipsis) && NextToken().is(K: tok::l_square)) {
653 E = ParseCXXPackIndexingExpression(PackIdExpression: E);
654 }
655 return E;
656}
657
658ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
659 // qualified-id:
660 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
661 // '::' unqualified-id
662 //
663 CXXScopeSpec SS;
664 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
665 /*ObjectHasErrors=*/ObjectHadErrors: false,
666 /*EnteringContext=*/false);
667
668 Token Replacement;
669 ExprResult Result =
670 tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
671 if (Result.isUnset()) {
672 // If the ExprResult is valid but null, then typo correction suggested a
673 // keyword replacement that needs to be reparsed.
674 UnconsumeToken(Consumed&: Replacement);
675 Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
676 }
677 assert(!Result.isUnset() && "Typo correction suggested a keyword replacement "
678 "for a previous keyword suggestion");
679 return Result;
680}
681
682ExprResult Parser::ParseLambdaExpression() {
683 // Parse lambda-introducer.
684 LambdaIntroducer Intro;
685 if (ParseLambdaIntroducer(Intro)) {
686 SkipUntil(T: tok::r_square, Flags: StopAtSemi);
687 SkipUntil(T: tok::l_brace, Flags: StopAtSemi);
688 SkipUntil(T: tok::r_brace, Flags: StopAtSemi);
689 return ExprError();
690 }
691
692 return ParseLambdaExpressionAfterIntroducer(Intro);
693}
694
695ExprResult Parser::TryParseLambdaExpression() {
696 assert(getLangOpts().CPlusPlus && Tok.is(tok::l_square) &&
697 "Not at the start of a possible lambda expression.");
698
699 const Token Next = NextToken();
700 if (Next.is(K: tok::eof)) // Nothing else to lookup here...
701 return ExprEmpty();
702
703 const Token After = GetLookAheadToken(N: 2);
704 // If lookahead indicates this is a lambda...
705 if (Next.is(K: tok::r_square) || // []
706 Next.is(K: tok::equal) || // [=
707 (Next.is(K: tok::amp) && // [&] or [&,
708 After.isOneOf(K1: tok::r_square, K2: tok::comma)) ||
709 (Next.is(K: tok::identifier) && // [identifier]
710 After.is(K: tok::r_square)) ||
711 Next.is(K: tok::ellipsis)) { // [...
712 return ParseLambdaExpression();
713 }
714
715 // If lookahead indicates an ObjC message send...
716 // [identifier identifier
717 if (Next.is(K: tok::identifier) && After.is(K: tok::identifier))
718 return ExprEmpty();
719
720 // Here, we're stuck: lambda introducers and Objective-C message sends are
721 // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a
722 // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of
723 // writing two routines to parse a lambda introducer, just try to parse
724 // a lambda introducer first, and fall back if that fails.
725 LambdaIntroducer Intro;
726 {
727 TentativeParsingAction TPA(*this);
728 LambdaIntroducerTentativeParse Tentative;
729 if (ParseLambdaIntroducer(Intro, Tentative: &Tentative)) {
730 TPA.Commit();
731 return ExprError();
732 }
733
734 switch (Tentative) {
735 case LambdaIntroducerTentativeParse::Success:
736 TPA.Commit();
737 break;
738
739 case LambdaIntroducerTentativeParse::Incomplete:
740 // Didn't fully parse the lambda-introducer, try again with a
741 // non-tentative parse.
742 TPA.Revert();
743 Intro = LambdaIntroducer();
744 if (ParseLambdaIntroducer(Intro))
745 return ExprError();
746 break;
747
748 case LambdaIntroducerTentativeParse::MessageSend:
749 case LambdaIntroducerTentativeParse::Invalid:
750 // Not a lambda-introducer, might be a message send.
751 TPA.Revert();
752 return ExprEmpty();
753 }
754 }
755
756 return ParseLambdaExpressionAfterIntroducer(Intro);
757}
758
759bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
760 LambdaIntroducerTentativeParse *Tentative) {
761 if (Tentative)
762 *Tentative = LambdaIntroducerTentativeParse::Success;
763
764 assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
765 BalancedDelimiterTracker T(*this, tok::l_square);
766 T.consumeOpen();
767
768 Intro.Range.setBegin(T.getOpenLocation());
769
770 bool First = true;
771
772 // Produce a diagnostic if we're not tentatively parsing; otherwise track
773 // that our parse has failed.
774 auto Invalid = [&](llvm::function_ref<void()> Action) {
775 if (Tentative) {
776 *Tentative = LambdaIntroducerTentativeParse::Invalid;
777 return false;
778 }
779 Action();
780 return true;
781 };
782
783 // Perform some irreversible action if this is a non-tentative parse;
784 // otherwise note that our actions were incomplete.
785 auto NonTentativeAction = [&](llvm::function_ref<void()> Action) {
786 if (Tentative)
787 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
788 else
789 Action();
790 };
791
792 // Parse capture-default.
793 if (Tok.is(K: tok::amp) &&
794 (NextToken().is(K: tok::comma) || NextToken().is(K: tok::r_square))) {
795 Intro.Default = LCD_ByRef;
796 Intro.DefaultLoc = ConsumeToken();
797 First = false;
798 if (!Tok.getIdentifierInfo()) {
799 // This can only be a lambda; no need for tentative parsing any more.
800 // '[[and]]' can still be an attribute, though.
801 Tentative = nullptr;
802 }
803 } else if (Tok.is(K: tok::equal)) {
804 Intro.Default = LCD_ByCopy;
805 Intro.DefaultLoc = ConsumeToken();
806 First = false;
807 Tentative = nullptr;
808 }
809
810 while (Tok.isNot(K: tok::r_square)) {
811 if (!First) {
812 if (Tok.isNot(K: tok::comma)) {
813 // Provide a completion for a lambda introducer here. Except
814 // in Objective-C, where this is Almost Surely meant to be a message
815 // send. In that case, fail here and let the ObjC message
816 // expression parser perform the completion.
817 if (Tok.is(K: tok::code_completion) &&
818 !(getLangOpts().ObjC && Tentative)) {
819 cutOffParsing();
820 Actions.CodeCompletion().CodeCompleteLambdaIntroducer(
821 S: getCurScope(), Intro,
822 /*AfterAmpersand=*/false);
823 break;
824 }
825
826 return Invalid([&] {
827 Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
828 });
829 }
830 ConsumeToken();
831 }
832
833 if (Tok.is(K: tok::code_completion)) {
834 cutOffParsing();
835 // If we're in Objective-C++ and we have a bare '[', then this is more
836 // likely to be a message receiver.
837 if (getLangOpts().ObjC && Tentative && First)
838 Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(S: getCurScope());
839 else
840 Actions.CodeCompletion().CodeCompleteLambdaIntroducer(
841 S: getCurScope(), Intro,
842 /*AfterAmpersand=*/false);
843 break;
844 }
845
846 First = false;
847
848 // Parse capture.
849 LambdaCaptureKind Kind = LCK_ByCopy;
850 LambdaCaptureInitKind InitKind = LambdaCaptureInitKind::NoInit;
851 SourceLocation Loc;
852 IdentifierInfo *Id = nullptr;
853 SourceLocation EllipsisLocs[4];
854 ExprResult Init;
855 SourceLocation LocStart = Tok.getLocation();
856
857 if (Tok.is(K: tok::star)) {
858 Loc = ConsumeToken();
859 if (Tok.is(K: tok::kw_this)) {
860 ConsumeToken();
861 Kind = LCK_StarThis;
862 } else {
863 return Invalid([&] {
864 Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
865 });
866 }
867 } else if (Tok.is(K: tok::kw_this)) {
868 Kind = LCK_This;
869 Loc = ConsumeToken();
870 } else if (Tok.isOneOf(K1: tok::amp, K2: tok::equal) &&
871 NextToken().isOneOf(K1: tok::comma, K2: tok::r_square) &&
872 Intro.Default == LCD_None) {
873 // We have a lone "&" or "=" which is either a misplaced capture-default
874 // or the start of a capture (in the "&" case) with the rest of the
875 // capture missing. Both are an error but a misplaced capture-default
876 // is more likely if we don't already have a capture default.
877 return Invalid(
878 [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });
879 } else {
880 TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLocs[0]);
881
882 if (Tok.is(K: tok::amp)) {
883 Kind = LCK_ByRef;
884 ConsumeToken();
885
886 if (Tok.is(K: tok::code_completion)) {
887 cutOffParsing();
888 Actions.CodeCompletion().CodeCompleteLambdaIntroducer(
889 S: getCurScope(), Intro,
890 /*AfterAmpersand=*/true);
891 break;
892 }
893 }
894
895 TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLocs[1]);
896
897 if (Tok.is(K: tok::identifier)) {
898 Id = Tok.getIdentifierInfo();
899 Loc = ConsumeToken();
900 } else if (Tok.is(K: tok::kw_this)) {
901 return Invalid([&] {
902 // FIXME: Suggest a fixit here.
903 Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
904 });
905 } else {
906 return Invalid([&] {
907 Diag(Tok.getLocation(), diag::err_expected_capture);
908 });
909 }
910
911 TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLocs[2]);
912
913 if (Tok.is(K: tok::l_paren)) {
914 BalancedDelimiterTracker Parens(*this, tok::l_paren);
915 Parens.consumeOpen();
916
917 InitKind = LambdaCaptureInitKind::DirectInit;
918
919 ExprVector Exprs;
920 if (Tentative) {
921 Parens.skipToEnd();
922 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
923 } else if (ParseExpressionList(Exprs)) {
924 Parens.skipToEnd();
925 Init = ExprError();
926 } else {
927 Parens.consumeClose();
928 Init = Actions.ActOnParenListExpr(L: Parens.getOpenLocation(),
929 R: Parens.getCloseLocation(),
930 Val: Exprs);
931 }
932 } else if (Tok.isOneOf(K1: tok::l_brace, K2: tok::equal)) {
933 // Each lambda init-capture forms its own full expression, which clears
934 // Actions.MaybeODRUseExprs. So create an expression evaluation context
935 // to save the necessary state, and restore it later.
936 EnterExpressionEvaluationContext EC(
937 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
938
939 if (TryConsumeToken(Expected: tok::equal))
940 InitKind = LambdaCaptureInitKind::CopyInit;
941 else
942 InitKind = LambdaCaptureInitKind::ListInit;
943
944 if (!Tentative) {
945 Init = ParseInitializer();
946 } else if (Tok.is(K: tok::l_brace)) {
947 BalancedDelimiterTracker Braces(*this, tok::l_brace);
948 Braces.consumeOpen();
949 Braces.skipToEnd();
950 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
951 } else {
952 // We're disambiguating this:
953 //
954 // [..., x = expr
955 //
956 // We need to find the end of the following expression in order to
957 // determine whether this is an Obj-C message send's receiver, a
958 // C99 designator, or a lambda init-capture.
959 //
960 // Parse the expression to find where it ends, and annotate it back
961 // onto the tokens. We would have parsed this expression the same way
962 // in either case: both the RHS of an init-capture and the RHS of an
963 // assignment expression are parsed as an initializer-clause, and in
964 // neither case can anything be added to the scope between the '[' and
965 // here.
966 //
967 // FIXME: This is horrible. Adding a mechanism to skip an expression
968 // would be much cleaner.
969 // FIXME: If there is a ',' before the next ']' or ':', we can skip to
970 // that instead. (And if we see a ':' with no matching '?', we can
971 // classify this as an Obj-C message send.)
972 SourceLocation StartLoc = Tok.getLocation();
973 InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
974 Init = ParseInitializer();
975 if (!Init.isInvalid())
976 Init = Actions.CorrectDelayedTyposInExpr(E: Init.get());
977
978 if (Tok.getLocation() != StartLoc) {
979 // Back out the lexing of the token after the initializer.
980 PP.RevertCachedTokens(N: 1);
981
982 // Replace the consumed tokens with an appropriate annotation.
983 Tok.setLocation(StartLoc);
984 Tok.setKind(tok::annot_primary_expr);
985 setExprAnnotation(Tok, ER: Init);
986 Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());
987 PP.AnnotateCachedTokens(Tok);
988
989 // Consume the annotated initializer.
990 ConsumeAnnotationToken();
991 }
992 }
993 }
994
995 TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLocs[3]);
996 }
997
998 // Check if this is a message send before we act on a possible init-capture.
999 if (Tentative && Tok.is(K: tok::identifier) &&
1000 NextToken().isOneOf(K1: tok::colon, K2: tok::r_square)) {
1001 // This can only be a message send. We're done with disambiguation.
1002 *Tentative = LambdaIntroducerTentativeParse::MessageSend;
1003 return false;
1004 }
1005
1006 // Ensure that any ellipsis was in the right place.
1007 SourceLocation EllipsisLoc;
1008 if (llvm::any_of(Range&: EllipsisLocs,
1009 P: [](SourceLocation Loc) { return Loc.isValid(); })) {
1010 // The '...' should appear before the identifier in an init-capture, and
1011 // after the identifier otherwise.
1012 bool InitCapture = InitKind != LambdaCaptureInitKind::NoInit;
1013 SourceLocation *ExpectedEllipsisLoc =
1014 !InitCapture ? &EllipsisLocs[2] :
1015 Kind == LCK_ByRef ? &EllipsisLocs[1] :
1016 &EllipsisLocs[0];
1017 EllipsisLoc = *ExpectedEllipsisLoc;
1018
1019 unsigned DiagID = 0;
1020 if (EllipsisLoc.isInvalid()) {
1021 DiagID = diag::err_lambda_capture_misplaced_ellipsis;
1022 for (SourceLocation Loc : EllipsisLocs) {
1023 if (Loc.isValid())
1024 EllipsisLoc = Loc;
1025 }
1026 } else {
1027 unsigned NumEllipses = std::accumulate(
1028 first: std::begin(arr&: EllipsisLocs), last: std::end(arr&: EllipsisLocs), init: 0,
1029 binary_op: [](int N, SourceLocation Loc) { return N + Loc.isValid(); });
1030 if (NumEllipses > 1)
1031 DiagID = diag::err_lambda_capture_multiple_ellipses;
1032 }
1033 if (DiagID) {
1034 NonTentativeAction([&] {
1035 // Point the diagnostic at the first misplaced ellipsis.
1036 SourceLocation DiagLoc;
1037 for (SourceLocation &Loc : EllipsisLocs) {
1038 if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) {
1039 DiagLoc = Loc;
1040 break;
1041 }
1042 }
1043 assert(DiagLoc.isValid() && "no location for diagnostic");
1044
1045 // Issue the diagnostic and produce fixits showing where the ellipsis
1046 // should have been written.
1047 auto &&D = Diag(Loc: DiagLoc, DiagID);
1048 if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) {
1049 SourceLocation ExpectedLoc =
1050 InitCapture ? Loc
1051 : Lexer::getLocForEndOfToken(
1052 Loc, Offset: 0, SM: PP.getSourceManager(), LangOpts: getLangOpts());
1053 D << InitCapture << FixItHint::CreateInsertion(InsertionLoc: ExpectedLoc, Code: "...");
1054 }
1055 for (SourceLocation &Loc : EllipsisLocs) {
1056 if (&Loc != ExpectedEllipsisLoc && Loc.isValid())
1057 D << FixItHint::CreateRemoval(RemoveRange: Loc);
1058 }
1059 });
1060 }
1061 }
1062
1063 // Process the init-capture initializers now rather than delaying until we
1064 // form the lambda-expression so that they can be handled in the context
1065 // enclosing the lambda-expression, rather than in the context of the
1066 // lambda-expression itself.
1067 ParsedType InitCaptureType;
1068 if (Init.isUsable())
1069 Init = Actions.CorrectDelayedTyposInExpr(E: Init.get());
1070 if (Init.isUsable()) {
1071 NonTentativeAction([&] {
1072 // Get the pointer and store it in an lvalue, so we can use it as an
1073 // out argument.
1074 Expr *InitExpr = Init.get();
1075 // This performs any lvalue-to-rvalue conversions if necessary, which
1076 // can affect what gets captured in the containing decl-context.
1077 InitCaptureType = Actions.actOnLambdaInitCaptureInitialization(
1078 Loc, ByRef: Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, Init&: InitExpr);
1079 Init = InitExpr;
1080 });
1081 }
1082
1083 SourceLocation LocEnd = PrevTokLocation;
1084
1085 Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,
1086 InitCaptureType, ExplicitRange: SourceRange(LocStart, LocEnd));
1087 }
1088
1089 T.consumeClose();
1090 Intro.Range.setEnd(T.getCloseLocation());
1091 return false;
1092}
1093
1094static void tryConsumeLambdaSpecifierToken(Parser &P,
1095 SourceLocation &MutableLoc,
1096 SourceLocation &StaticLoc,
1097 SourceLocation &ConstexprLoc,
1098 SourceLocation &ConstevalLoc,
1099 SourceLocation &DeclEndLoc) {
1100 assert(MutableLoc.isInvalid());
1101 assert(StaticLoc.isInvalid());
1102 assert(ConstexprLoc.isInvalid());
1103 assert(ConstevalLoc.isInvalid());
1104 // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc
1105 // to the final of those locations. Emit an error if we have multiple
1106 // copies of those keywords and recover.
1107
1108 auto ConsumeLocation = [&P, &DeclEndLoc](SourceLocation &SpecifierLoc,
1109 int DiagIndex) {
1110 if (SpecifierLoc.isValid()) {
1111 P.Diag(P.getCurToken().getLocation(),
1112 diag::err_lambda_decl_specifier_repeated)
1113 << DiagIndex
1114 << FixItHint::CreateRemoval(P.getCurToken().getLocation());
1115 }
1116 SpecifierLoc = P.ConsumeToken();
1117 DeclEndLoc = SpecifierLoc;
1118 };
1119
1120 while (true) {
1121 switch (P.getCurToken().getKind()) {
1122 case tok::kw_mutable:
1123 ConsumeLocation(MutableLoc, 0);
1124 break;
1125 case tok::kw_static:
1126 ConsumeLocation(StaticLoc, 1);
1127 break;
1128 case tok::kw_constexpr:
1129 ConsumeLocation(ConstexprLoc, 2);
1130 break;
1131 case tok::kw_consteval:
1132 ConsumeLocation(ConstevalLoc, 3);
1133 break;
1134 default:
1135 return;
1136 }
1137 }
1138}
1139
1140static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc,
1141 DeclSpec &DS) {
1142 if (StaticLoc.isValid()) {
1143 P.Diag(StaticLoc, !P.getLangOpts().CPlusPlus23
1144 ? diag::err_static_lambda
1145 : diag::warn_cxx20_compat_static_lambda);
1146 const char *PrevSpec = nullptr;
1147 unsigned DiagID = 0;
1148 DS.SetStorageClassSpec(S&: P.getActions(), SC: DeclSpec::SCS_static, Loc: StaticLoc,
1149 PrevSpec, DiagID,
1150 Policy: P.getActions().getASTContext().getPrintingPolicy());
1151 assert(PrevSpec == nullptr && DiagID == 0 &&
1152 "Static cannot have been set previously!");
1153 }
1154}
1155
1156static void
1157addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc,
1158 DeclSpec &DS) {
1159 if (ConstexprLoc.isValid()) {
1160 P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus17
1161 ? diag::ext_constexpr_on_lambda_cxx17
1162 : diag::warn_cxx14_compat_constexpr_on_lambda);
1163 const char *PrevSpec = nullptr;
1164 unsigned DiagID = 0;
1165 DS.SetConstexprSpec(ConstexprKind: ConstexprSpecKind::Constexpr, Loc: ConstexprLoc, PrevSpec,
1166 DiagID);
1167 assert(PrevSpec == nullptr && DiagID == 0 &&
1168 "Constexpr cannot have been set previously!");
1169 }
1170}
1171
1172static void addConstevalToLambdaDeclSpecifier(Parser &P,
1173 SourceLocation ConstevalLoc,
1174 DeclSpec &DS) {
1175 if (ConstevalLoc.isValid()) {
1176 P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval);
1177 const char *PrevSpec = nullptr;
1178 unsigned DiagID = 0;
1179 DS.SetConstexprSpec(ConstexprKind: ConstexprSpecKind::Consteval, Loc: ConstevalLoc, PrevSpec,
1180 DiagID);
1181 if (DiagID != 0)
1182 P.Diag(Loc: ConstevalLoc, DiagID) << PrevSpec;
1183 }
1184}
1185
1186static void DiagnoseStaticSpecifierRestrictions(Parser &P,
1187 SourceLocation StaticLoc,
1188 SourceLocation MutableLoc,
1189 const LambdaIntroducer &Intro) {
1190 if (StaticLoc.isInvalid())
1191 return;
1192
1193 // [expr.prim.lambda.general] p4
1194 // The lambda-specifier-seq shall not contain both mutable and static.
1195 // If the lambda-specifier-seq contains static, there shall be no
1196 // lambda-capture.
1197 if (MutableLoc.isValid())
1198 P.Diag(StaticLoc, diag::err_static_mutable_lambda);
1199 if (Intro.hasLambdaCapture()) {
1200 P.Diag(StaticLoc, diag::err_static_lambda_captures);
1201 }
1202}
1203
1204ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
1205 LambdaIntroducer &Intro) {
1206 SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
1207 if (getLangOpts().HLSL)
1208 Diag(LambdaBeginLoc, diag::ext_hlsl_lambda) << /*HLSL*/ 1;
1209 else
1210 Diag(LambdaBeginLoc, getLangOpts().CPlusPlus11
1211 ? diag::warn_cxx98_compat_lambda
1212 : diag::ext_lambda)
1213 << /*C++*/ 0;
1214
1215 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
1216 "lambda expression parsing");
1217
1218 // Parse lambda-declarator[opt].
1219 DeclSpec DS(AttrFactory);
1220 Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::LambdaExpr);
1221 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1222
1223 ParseScope LambdaScope(this, Scope::LambdaScope | Scope::DeclScope |
1224 Scope::FunctionDeclarationScope |
1225 Scope::FunctionPrototypeScope);
1226
1227 Actions.PushLambdaScope();
1228 Actions.ActOnLambdaExpressionAfterIntroducer(Intro, CurContext: getCurScope());
1229
1230 ParsedAttributes Attributes(AttrFactory);
1231 if (getLangOpts().CUDA) {
1232 // In CUDA code, GNU attributes are allowed to appear immediately after the
1233 // "[...]", even if there is no "(...)" before the lambda body.
1234 //
1235 // Note that we support __noinline__ as a keyword in this mode and thus
1236 // it has to be separately handled.
1237 while (true) {
1238 if (Tok.is(K: tok::kw___noinline__)) {
1239 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1240 SourceLocation AttrNameLoc = ConsumeToken();
1241 Attributes.addNew(attrName: AttrName, attrRange: AttrNameLoc, /*ScopeName=*/scopeName: nullptr,
1242 scopeLoc: AttrNameLoc, /*ArgsUnion=*/args: nullptr,
1243 /*numArgs=*/0, form: tok::kw___noinline__);
1244 } else if (Tok.is(K: tok::kw___attribute))
1245 ParseGNUAttributes(Attrs&: Attributes, /*LatePArsedAttrList=*/LateAttrs: nullptr, D: &D);
1246 else
1247 break;
1248 }
1249
1250 D.takeAttributes(attrs&: Attributes);
1251 }
1252
1253 MultiParseScope TemplateParamScope(*this);
1254 if (Tok.is(K: tok::less)) {
1255 Diag(Tok, getLangOpts().CPlusPlus20
1256 ? diag::warn_cxx17_compat_lambda_template_parameter_list
1257 : diag::ext_lambda_template_parameter_list);
1258
1259 SmallVector<NamedDecl*, 4> TemplateParams;
1260 SourceLocation LAngleLoc, RAngleLoc;
1261 if (ParseTemplateParameters(TemplateScopes&: TemplateParamScope,
1262 Depth: CurTemplateDepthTracker.getDepth(),
1263 TemplateParams, LAngleLoc, RAngleLoc)) {
1264 Actions.ActOnLambdaError(StartLoc: LambdaBeginLoc, CurScope: getCurScope());
1265 return ExprError();
1266 }
1267
1268 if (TemplateParams.empty()) {
1269 Diag(RAngleLoc,
1270 diag::err_lambda_template_parameter_list_empty);
1271 } else {
1272 // We increase the template depth before recursing into a requires-clause.
1273 //
1274 // This depth is used for setting up a LambdaScopeInfo (in
1275 // Sema::RecordParsingTemplateParameterDepth), which is used later when
1276 // inventing template parameters in InventTemplateParameter.
1277 //
1278 // This way, abbreviated generic lambdas could have different template
1279 // depths, avoiding substitution into the wrong template parameters during
1280 // constraint satisfaction check.
1281 ++CurTemplateDepthTracker;
1282 ExprResult RequiresClause;
1283 if (TryConsumeToken(Expected: tok::kw_requires)) {
1284 RequiresClause =
1285 Actions.ActOnRequiresClause(ConstraintExpr: ParseConstraintLogicalOrExpression(
1286 /*IsTrailingRequiresClause=*/false));
1287 if (RequiresClause.isInvalid())
1288 SkipUntil(Toks: {tok::l_brace, tok::l_paren}, Flags: StopAtSemi | StopBeforeMatch);
1289 }
1290
1291 Actions.ActOnLambdaExplicitTemplateParameterList(
1292 Intro, LAngleLoc, TParams: TemplateParams, RAngleLoc, RequiresClause);
1293 }
1294 }
1295
1296 // Implement WG21 P2173, which allows attributes immediately before the
1297 // lambda declarator and applies them to the corresponding function operator
1298 // or operator template declaration. We accept this as a conforming extension
1299 // in all language modes that support lambdas.
1300 if (isCXX11AttributeSpecifier() !=
1301 CXX11AttributeKind::NotAttributeSpecifier) {
1302 Diag(Tok, getLangOpts().CPlusPlus23
1303 ? diag::warn_cxx20_compat_decl_attrs_on_lambda
1304 : diag::ext_decl_attrs_on_lambda)
1305 << Tok.getIdentifierInfo() << Tok.isRegularKeywordAttribute();
1306 MaybeParseCXX11Attributes(D);
1307 }
1308
1309 TypeResult TrailingReturnType;
1310 SourceLocation TrailingReturnTypeLoc;
1311 SourceLocation LParenLoc, RParenLoc;
1312 SourceLocation DeclEndLoc;
1313 bool HasParentheses = false;
1314 bool HasSpecifiers = false;
1315 SourceLocation MutableLoc;
1316
1317 ParseScope Prototype(this, Scope::FunctionPrototypeScope |
1318 Scope::FunctionDeclarationScope |
1319 Scope::DeclScope);
1320
1321 // Parse parameter-declaration-clause.
1322 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
1323 SourceLocation EllipsisLoc;
1324
1325 if (Tok.is(K: tok::l_paren)) {
1326 BalancedDelimiterTracker T(*this, tok::l_paren);
1327 T.consumeOpen();
1328 LParenLoc = T.getOpenLocation();
1329
1330 if (Tok.isNot(K: tok::r_paren)) {
1331 Actions.RecordParsingTemplateParameterDepth(
1332 Depth: CurTemplateDepthTracker.getOriginalDepth());
1333
1334 ParseParameterDeclarationClause(D, attrs&: Attributes, ParamInfo, EllipsisLoc);
1335 // For a generic lambda, each 'auto' within the parameter declaration
1336 // clause creates a template type parameter, so increment the depth.
1337 // If we've parsed any explicit template parameters, then the depth will
1338 // have already been incremented. So we make sure that at most a single
1339 // depth level is added.
1340 if (Actions.getCurGenericLambda())
1341 CurTemplateDepthTracker.setAddedDepth(1);
1342 }
1343
1344 T.consumeClose();
1345 DeclEndLoc = RParenLoc = T.getCloseLocation();
1346 HasParentheses = true;
1347 }
1348
1349 HasSpecifiers =
1350 Tok.isOneOf(K1: tok::kw_mutable, Ks: tok::arrow, Ks: tok::kw___attribute,
1351 Ks: tok::kw_constexpr, Ks: tok::kw_consteval, Ks: tok::kw_static,
1352 Ks: tok::kw___private, Ks: tok::kw___global, Ks: tok::kw___local,
1353 Ks: tok::kw___constant, Ks: tok::kw___generic, Ks: tok::kw_groupshared,
1354 Ks: tok::kw_requires, Ks: tok::kw_noexcept) ||
1355 Tok.isRegularKeywordAttribute() ||
1356 (Tok.is(K: tok::l_square) && NextToken().is(K: tok::l_square));
1357
1358 if (HasSpecifiers && !HasParentheses && !getLangOpts().CPlusPlus23) {
1359 // It's common to forget that one needs '()' before 'mutable', an
1360 // attribute specifier, the result type, or the requires clause. Deal with
1361 // this.
1362 Diag(Tok, diag::ext_lambda_missing_parens)
1363 << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
1364 }
1365
1366 if (HasParentheses || HasSpecifiers) {
1367 // GNU-style attributes must be parsed before the mutable specifier to
1368 // be compatible with GCC. MSVC-style attributes must be parsed before
1369 // the mutable specifier to be compatible with MSVC.
1370 MaybeParseAttributes(WhichAttrKinds: PAKM_GNU | PAKM_Declspec, Attrs&: Attributes);
1371 // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update
1372 // the DeclEndLoc.
1373 SourceLocation ConstexprLoc;
1374 SourceLocation ConstevalLoc;
1375 SourceLocation StaticLoc;
1376
1377 tryConsumeLambdaSpecifierToken(P&: *this, MutableLoc, StaticLoc, ConstexprLoc,
1378 ConstevalLoc, DeclEndLoc);
1379
1380 DiagnoseStaticSpecifierRestrictions(P&: *this, StaticLoc, MutableLoc, Intro);
1381
1382 addStaticToLambdaDeclSpecifier(P&: *this, StaticLoc, DS);
1383 addConstexprToLambdaDeclSpecifier(P&: *this, ConstexprLoc, DS);
1384 addConstevalToLambdaDeclSpecifier(P&: *this, ConstevalLoc, DS);
1385 }
1386
1387 Actions.ActOnLambdaClosureParameters(LambdaScope: getCurScope(), ParamInfo);
1388
1389 if (!HasParentheses)
1390 Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc);
1391
1392 if (HasSpecifiers || HasParentheses) {
1393 // Parse exception-specification[opt].
1394 ExceptionSpecificationType ESpecType = EST_None;
1395 SourceRange ESpecRange;
1396 SmallVector<ParsedType, 2> DynamicExceptions;
1397 SmallVector<SourceRange, 2> DynamicExceptionRanges;
1398 ExprResult NoexceptExpr;
1399 CachedTokens *ExceptionSpecTokens;
1400
1401 ESpecType = tryParseExceptionSpecification(
1402 /*Delayed=*/false, SpecificationRange&: ESpecRange, DynamicExceptions,
1403 DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens);
1404
1405 if (ESpecType != EST_None)
1406 DeclEndLoc = ESpecRange.getEnd();
1407
1408 // Parse attribute-specifier[opt].
1409 if (MaybeParseCXX11Attributes(Attrs&: Attributes))
1410 DeclEndLoc = Attributes.Range.getEnd();
1411
1412 // Parse OpenCL addr space attribute.
1413 if (Tok.isOneOf(K1: tok::kw___private, Ks: tok::kw___global, Ks: tok::kw___local,
1414 Ks: tok::kw___constant, Ks: tok::kw___generic)) {
1415 ParseOpenCLQualifiers(Attrs&: DS.getAttributes());
1416 ConsumeToken();
1417 }
1418
1419 SourceLocation FunLocalRangeEnd = DeclEndLoc;
1420
1421 // Parse trailing-return-type[opt].
1422 if (Tok.is(K: tok::arrow)) {
1423 FunLocalRangeEnd = Tok.getLocation();
1424 SourceRange Range;
1425 TrailingReturnType =
1426 ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false);
1427 TrailingReturnTypeLoc = Range.getBegin();
1428 if (Range.getEnd().isValid())
1429 DeclEndLoc = Range.getEnd();
1430 }
1431
1432 SourceLocation NoLoc;
1433 D.AddTypeInfo(TI: DeclaratorChunk::getFunction(
1434 /*HasProto=*/true,
1435 /*IsAmbiguous=*/false, LParenLoc, Params: ParamInfo.data(),
1436 NumParams: ParamInfo.size(), EllipsisLoc, RParenLoc,
1437 /*RefQualifierIsLvalueRef=*/true,
1438 /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType,
1439 ESpecRange, Exceptions: DynamicExceptions.data(),
1440 ExceptionRanges: DynamicExceptionRanges.data(), NumExceptions: DynamicExceptions.size(),
1441 NoexceptExpr: NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
1442 /*ExceptionSpecTokens*/ nullptr,
1443 /*DeclsInPrototype=*/{}, LocalRangeBegin: LParenLoc, LocalRangeEnd: FunLocalRangeEnd, TheDeclarator&: D,
1444 TrailingReturnType, TrailingReturnTypeLoc, MethodQualifiers: &DS),
1445 attrs: std::move(Attributes), EndLoc: DeclEndLoc);
1446
1447 // We have called ActOnLambdaClosureQualifiers for parentheses-less cases
1448 // above.
1449 if (HasParentheses)
1450 Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc);
1451
1452 if (HasParentheses && Tok.is(K: tok::kw_requires))
1453 ParseTrailingRequiresClause(D);
1454 }
1455
1456 // Emit a warning if we see a CUDA host/device/global attribute
1457 // after '(...)'. nvcc doesn't accept this.
1458 if (getLangOpts().CUDA) {
1459 for (const ParsedAttr &A : Attributes)
1460 if (A.getKind() == ParsedAttr::AT_CUDADevice ||
1461 A.getKind() == ParsedAttr::AT_CUDAHost ||
1462 A.getKind() == ParsedAttr::AT_CUDAGlobal)
1463 Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
1464 << A.getAttrName()->getName();
1465 }
1466
1467 Prototype.Exit();
1468
1469 // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
1470 // it.
1471 unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope |
1472 Scope::CompoundStmtScope;
1473 ParseScope BodyScope(this, ScopeFlags);
1474
1475 Actions.ActOnStartOfLambdaDefinition(Intro, ParamInfo&: D, DS);
1476
1477 // Parse compound-statement.
1478 if (!Tok.is(K: tok::l_brace)) {
1479 Diag(Tok, diag::err_expected_lambda_body);
1480 Actions.ActOnLambdaError(StartLoc: LambdaBeginLoc, CurScope: getCurScope());
1481 return ExprError();
1482 }
1483
1484 StmtResult Stmt(ParseCompoundStatementBody());
1485 BodyScope.Exit();
1486 TemplateParamScope.Exit();
1487 LambdaScope.Exit();
1488
1489 if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid() &&
1490 !D.isInvalidType())
1491 return Actions.ActOnLambdaExpr(StartLoc: LambdaBeginLoc, Body: Stmt.get());
1492
1493 Actions.ActOnLambdaError(StartLoc: LambdaBeginLoc, CurScope: getCurScope());
1494 return ExprError();
1495}
1496
1497ExprResult Parser::ParseCXXCasts() {
1498 tok::TokenKind Kind = Tok.getKind();
1499 const char *CastName = nullptr; // For error messages
1500
1501 switch (Kind) {
1502 default: llvm_unreachable("Unknown C++ cast!");
1503 case tok::kw_addrspace_cast: CastName = "addrspace_cast"; break;
1504 case tok::kw_const_cast: CastName = "const_cast"; break;
1505 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;
1506 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
1507 case tok::kw_static_cast: CastName = "static_cast"; break;
1508 }
1509
1510 SourceLocation OpLoc = ConsumeToken();
1511 SourceLocation LAngleBracketLoc = Tok.getLocation();
1512
1513 // Check for "<::" which is parsed as "[:". If found, fix token stream,
1514 // diagnose error, suggest fix, and recover parsing.
1515 if (Tok.is(K: tok::l_square) && Tok.getLength() == 2) {
1516 Token Next = NextToken();
1517 if (Next.is(K: tok::colon) && areTokensAdjacent(First: Tok, Second: Next))
1518 FixDigraph(P&: *this, PP, DigraphToken&: Tok, ColonToken&: Next, Kind, /*AtDigraph*/true);
1519 }
1520
1521 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
1522 return ExprError();
1523
1524 // Parse the common declaration-specifiers piece.
1525 DeclSpec DS(AttrFactory);
1526 ParseSpecifierQualifierList(DS, /*AccessSpecifier=*/AS: AS_none,
1527 DSC: DeclSpecContext::DSC_type_specifier);
1528
1529 // Parse the abstract-declarator, if present.
1530 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1531 DeclaratorContext::TypeName);
1532 ParseDeclarator(D&: DeclaratorInfo);
1533
1534 SourceLocation RAngleBracketLoc = Tok.getLocation();
1535
1536 if (ExpectAndConsume(tok::greater))
1537 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
1538
1539 BalancedDelimiterTracker T(*this, tok::l_paren);
1540
1541 if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))
1542 return ExprError();
1543
1544 ExprResult Result = ParseExpression();
1545
1546 // Match the ')'.
1547 T.consumeClose();
1548
1549 if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType())
1550 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
1551 LAngleBracketLoc, D&: DeclaratorInfo,
1552 RAngleBracketLoc,
1553 LParenLoc: T.getOpenLocation(), E: Result.get(),
1554 RParenLoc: T.getCloseLocation());
1555
1556 return Result;
1557}
1558
1559ExprResult Parser::ParseCXXTypeid() {
1560 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
1561
1562 SourceLocation OpLoc = ConsumeToken();
1563 SourceLocation LParenLoc, RParenLoc;
1564 BalancedDelimiterTracker T(*this, tok::l_paren);
1565
1566 // typeid expressions are always parenthesized.
1567 if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))
1568 return ExprError();
1569 LParenLoc = T.getOpenLocation();
1570
1571 ExprResult Result;
1572
1573 // C++0x [expr.typeid]p3:
1574 // When typeid is applied to an expression other than an lvalue of a
1575 // polymorphic class type [...] The expression is an unevaluated
1576 // operand (Clause 5).
1577 //
1578 // Note that we can't tell whether the expression is an lvalue of a
1579 // polymorphic class type until after we've parsed the expression; we
1580 // speculatively assume the subexpression is unevaluated, and fix it up
1581 // later.
1582 //
1583 // We enter the unevaluated context before trying to determine whether we
1584 // have a type-id, because the tentative parse logic will try to resolve
1585 // names, and must treat them as unevaluated.
1586 EnterExpressionEvaluationContext Unevaluated(
1587 Actions, Sema::ExpressionEvaluationContext::Unevaluated,
1588 Sema::ReuseLambdaContextDecl);
1589
1590 if (isTypeIdInParens()) {
1591 TypeResult Ty = ParseTypeName();
1592
1593 // Match the ')'.
1594 T.consumeClose();
1595 RParenLoc = T.getCloseLocation();
1596 if (Ty.isInvalid() || RParenLoc.isInvalid())
1597 return ExprError();
1598
1599 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
1600 TyOrExpr: Ty.get().getAsOpaquePtr(), RParenLoc);
1601 } else {
1602 Result = ParseExpression();
1603
1604 // Match the ')'.
1605 if (Result.isInvalid())
1606 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1607 else {
1608 T.consumeClose();
1609 RParenLoc = T.getCloseLocation();
1610 if (RParenLoc.isInvalid())
1611 return ExprError();
1612
1613 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
1614 TyOrExpr: Result.get(), RParenLoc);
1615 }
1616 }
1617
1618 return Result;
1619}
1620
1621ExprResult Parser::ParseCXXUuidof() {
1622 assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
1623
1624 SourceLocation OpLoc = ConsumeToken();
1625 BalancedDelimiterTracker T(*this, tok::l_paren);
1626
1627 // __uuidof expressions are always parenthesized.
1628 if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))
1629 return ExprError();
1630
1631 ExprResult Result;
1632
1633 if (isTypeIdInParens()) {
1634 TypeResult Ty = ParseTypeName();
1635
1636 // Match the ')'.
1637 T.consumeClose();
1638
1639 if (Ty.isInvalid())
1640 return ExprError();
1641
1642 Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc: T.getOpenLocation(), /*isType=*/true,
1643 TyOrExpr: Ty.get().getAsOpaquePtr(),
1644 RParenLoc: T.getCloseLocation());
1645 } else {
1646 EnterExpressionEvaluationContext Unevaluated(
1647 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1648 Result = ParseExpression();
1649
1650 // Match the ')'.
1651 if (Result.isInvalid())
1652 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1653 else {
1654 T.consumeClose();
1655
1656 Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc: T.getOpenLocation(),
1657 /*isType=*/false,
1658 TyOrExpr: Result.get(), RParenLoc: T.getCloseLocation());
1659 }
1660 }
1661
1662 return Result;
1663}
1664
1665ExprResult
1666Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
1667 tok::TokenKind OpKind,
1668 CXXScopeSpec &SS,
1669 ParsedType ObjectType) {
1670 // If the last component of the (optional) nested-name-specifier is
1671 // template[opt] simple-template-id, it has already been annotated.
1672 UnqualifiedId FirstTypeName;
1673 SourceLocation CCLoc;
1674 if (Tok.is(K: tok::identifier)) {
1675 FirstTypeName.setIdentifier(Id: Tok.getIdentifierInfo(), IdLoc: Tok.getLocation());
1676 ConsumeToken();
1677 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1678 CCLoc = ConsumeToken();
1679 } else if (Tok.is(K: tok::annot_template_id)) {
1680 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok);
1681 // FIXME: Carry on and build an AST representation for tooling.
1682 if (TemplateId->isInvalid())
1683 return ExprError();
1684 FirstTypeName.setTemplateId(TemplateId);
1685 ConsumeAnnotationToken();
1686 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1687 CCLoc = ConsumeToken();
1688 } else {
1689 assert(SS.isEmpty() && "missing last component of nested name specifier");
1690 FirstTypeName.setIdentifier(Id: nullptr, IdLoc: SourceLocation());
1691 }
1692
1693 // Parse the tilde.
1694 assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
1695 SourceLocation TildeLoc = ConsumeToken();
1696
1697 if (Tok.is(K: tok::kw_decltype) && !FirstTypeName.isValid()) {
1698 DeclSpec DS(AttrFactory);
1699 ParseDecltypeSpecifier(DS);
1700 if (DS.getTypeSpecType() == TST_error)
1701 return ExprError();
1702 return Actions.ActOnPseudoDestructorExpr(S: getCurScope(), Base, OpLoc, OpKind,
1703 TildeLoc, DS);
1704 }
1705
1706 if (!Tok.is(K: tok::identifier)) {
1707 Diag(Tok, diag::err_destructor_tilde_identifier);
1708 return ExprError();
1709 }
1710
1711 // pack-index-specifier
1712 if (GetLookAheadToken(N: 1).is(K: tok::ellipsis) &&
1713 GetLookAheadToken(N: 2).is(K: tok::l_square)) {
1714 DeclSpec DS(AttrFactory);
1715 ParsePackIndexingType(DS);
1716 return Actions.ActOnPseudoDestructorExpr(S: getCurScope(), Base, OpLoc, OpKind,
1717 TildeLoc, DS);
1718 }
1719
1720 // Parse the second type.
1721 UnqualifiedId SecondTypeName;
1722 IdentifierInfo *Name = Tok.getIdentifierInfo();
1723 SourceLocation NameLoc = ConsumeToken();
1724 SecondTypeName.setIdentifier(Id: Name, IdLoc: NameLoc);
1725
1726 // If there is a '<', the second type name is a template-id. Parse
1727 // it as such.
1728 //
1729 // FIXME: This is not a context in which a '<' is assumed to start a template
1730 // argument list. This affects examples such as
1731 // void f(auto *p) { p->~X<int>(); }
1732 // ... but there's no ambiguity, and nowhere to write 'template' in such an
1733 // example, so we accept it anyway.
1734 if (Tok.is(K: tok::less) &&
1735 ParseUnqualifiedIdTemplateId(
1736 SS, ObjectType, ObjectHadErrors: Base && Base->containsErrors(), TemplateKWLoc: SourceLocation(),
1737 Name, NameLoc, EnteringContext: false, Id&: SecondTypeName,
1738 /*AssumeTemplateId=*/true))
1739 return ExprError();
1740
1741 return Actions.ActOnPseudoDestructorExpr(S: getCurScope(), Base, OpLoc, OpKind,
1742 SS, FirstTypeName, CCLoc, TildeLoc,
1743 SecondTypeName);
1744}
1745
1746ExprResult Parser::ParseCXXBoolLiteral() {
1747 tok::TokenKind Kind = Tok.getKind();
1748 return Actions.ActOnCXXBoolLiteral(OpLoc: ConsumeToken(), Kind);
1749}
1750
1751ExprResult Parser::ParseThrowExpression() {
1752 assert(Tok.is(tok::kw_throw) && "Not throw!");
1753 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token.
1754
1755 // If the current token isn't the start of an assignment-expression,
1756 // then the expression is not present. This handles things like:
1757 // "C ? throw : (void)42", which is crazy but legal.
1758 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common.
1759 case tok::semi:
1760 case tok::r_paren:
1761 case tok::r_square:
1762 case tok::r_brace:
1763 case tok::colon:
1764 case tok::comma:
1765 return Actions.ActOnCXXThrow(S: getCurScope(), OpLoc: ThrowLoc, expr: nullptr);
1766
1767 default:
1768 ExprResult Expr(ParseAssignmentExpression());
1769 if (Expr.isInvalid()) return Expr;
1770 return Actions.ActOnCXXThrow(S: getCurScope(), OpLoc: ThrowLoc, expr: Expr.get());
1771 }
1772}
1773
1774ExprResult Parser::ParseCoyieldExpression() {
1775 assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");
1776
1777 SourceLocation Loc = ConsumeToken();
1778 ExprResult Expr = Tok.is(K: tok::l_brace) ? ParseBraceInitializer()
1779 : ParseAssignmentExpression();
1780 if (!Expr.isInvalid())
1781 Expr = Actions.ActOnCoyieldExpr(S: getCurScope(), KwLoc: Loc, E: Expr.get());
1782 return Expr;
1783}
1784
1785ExprResult Parser::ParseCXXThis() {
1786 assert(Tok.is(tok::kw_this) && "Not 'this'!");
1787 SourceLocation ThisLoc = ConsumeToken();
1788 return Actions.ActOnCXXThis(Loc: ThisLoc);
1789}
1790
1791ExprResult
1792Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
1793 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1794 DeclaratorContext::FunctionalCast);
1795 ParsedType TypeRep = Actions.ActOnTypeName(D&: DeclaratorInfo).get();
1796
1797 assert((Tok.is(tok::l_paren) ||
1798 (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)))
1799 && "Expected '(' or '{'!");
1800
1801 if (Tok.is(K: tok::l_brace)) {
1802 PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());
1803 ExprResult Init = ParseBraceInitializer();
1804 if (Init.isInvalid())
1805 return Init;
1806 Expr *InitList = Init.get();
1807 return Actions.ActOnCXXTypeConstructExpr(
1808 TypeRep, LParenOrBraceLoc: InitList->getBeginLoc(), Exprs: MultiExprArg(&InitList, 1),
1809 RParenOrBraceLoc: InitList->getEndLoc(), /*ListInitialization=*/true);
1810 } else {
1811 BalancedDelimiterTracker T(*this, tok::l_paren);
1812 T.consumeOpen();
1813
1814 PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());
1815
1816 ExprVector Exprs;
1817
1818 auto RunSignatureHelp = [&]() {
1819 QualType PreferredType;
1820 if (TypeRep)
1821 PreferredType =
1822 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
1823 Type: TypeRep.get()->getCanonicalTypeInternal(), Loc: DS.getEndLoc(),
1824 Args: Exprs, OpenParLoc: T.getOpenLocation(), /*Braced=*/false);
1825 CalledSignatureHelp = true;
1826 return PreferredType;
1827 };
1828
1829 if (Tok.isNot(K: tok::r_paren)) {
1830 if (ParseExpressionList(Exprs, ExpressionStarts: [&] {
1831 PreferredType.enterFunctionArgument(Tok.getLocation(),
1832 RunSignatureHelp);
1833 })) {
1834 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1835 RunSignatureHelp();
1836 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1837 return ExprError();
1838 }
1839 }
1840
1841 // Match the ')'.
1842 T.consumeClose();
1843
1844 // TypeRep could be null, if it references an invalid typedef.
1845 if (!TypeRep)
1846 return ExprError();
1847
1848 return Actions.ActOnCXXTypeConstructExpr(TypeRep, LParenOrBraceLoc: T.getOpenLocation(),
1849 Exprs, RParenOrBraceLoc: T.getCloseLocation(),
1850 /*ListInitialization=*/false);
1851 }
1852}
1853
1854Parser::DeclGroupPtrTy
1855Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
1856 ParsedAttributes &Attrs) {
1857 assert(Tok.is(tok::kw_using) && "Expected using");
1858 assert((Context == DeclaratorContext::ForInit ||
1859 Context == DeclaratorContext::SelectionInit) &&
1860 "Unexpected Declarator Context");
1861 DeclGroupPtrTy DG;
1862 SourceLocation DeclStart = ConsumeToken(), DeclEnd;
1863
1864 DG = ParseUsingDeclaration(Context, TemplateInfo: {}, UsingLoc: DeclStart, DeclEnd, Attrs, AS: AS_none);
1865 if (!DG)
1866 return DG;
1867
1868 Diag(DeclStart, !getLangOpts().CPlusPlus23
1869 ? diag::ext_alias_in_init_statement
1870 : diag::warn_cxx20_alias_in_init_statement)
1871 << SourceRange(DeclStart, DeclEnd);
1872
1873 return DG;
1874}
1875
1876Sema::ConditionResult
1877Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
1878 Sema::ConditionKind CK, bool MissingOK,
1879 ForRangeInfo *FRI, bool EnterForConditionScope) {
1880 // Helper to ensure we always enter a continue/break scope if requested.
1881 struct ForConditionScopeRAII {
1882 Scope *S;
1883 void enter(bool IsConditionVariable) {
1884 if (S) {
1885 S->AddFlags(Flags: Scope::BreakScope | Scope::ContinueScope);
1886 S->setIsConditionVarScope(IsConditionVariable);
1887 }
1888 }
1889 ~ForConditionScopeRAII() {
1890 if (S)
1891 S->setIsConditionVarScope(false);
1892 }
1893 } ForConditionScope{.S: EnterForConditionScope ? getCurScope() : nullptr};
1894
1895 ParenBraceBracketBalancer BalancerRAIIObj(*this);
1896 PreferredType.enterCondition(Actions, Tok.getLocation());
1897
1898 if (Tok.is(K: tok::code_completion)) {
1899 cutOffParsing();
1900 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1901 S: getCurScope(), CompletionContext: SemaCodeCompletion::PCC_Condition);
1902 return Sema::ConditionError();
1903 }
1904
1905 ParsedAttributes attrs(AttrFactory);
1906 MaybeParseCXX11Attributes(Attrs&: attrs);
1907
1908 const auto WarnOnInit = [this, &CK] {
1909 Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
1910 ? diag::warn_cxx14_compat_init_statement
1911 : diag::ext_init_statement)
1912 << (CK == Sema::ConditionKind::Switch);
1913 };
1914
1915 // Determine what kind of thing we have.
1916 switch (isCXXConditionDeclarationOrInitStatement(CanBeInitStmt: InitStmt, CanBeForRangeDecl: FRI)) {
1917 case ConditionOrInitStatement::Expression: {
1918 // If this is a for loop, we're entering its condition.
1919 ForConditionScope.enter(/*IsConditionVariable=*/false);
1920
1921 ProhibitAttributes(Attrs&: attrs);
1922
1923 // We can have an empty expression here.
1924 // if (; true);
1925 if (InitStmt && Tok.is(K: tok::semi)) {
1926 WarnOnInit();
1927 SourceLocation SemiLoc = Tok.getLocation();
1928 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID()) {
1929 Diag(SemiLoc, diag::warn_empty_init_statement)
1930 << (CK == Sema::ConditionKind::Switch)
1931 << FixItHint::CreateRemoval(SemiLoc);
1932 }
1933 ConsumeToken();
1934 *InitStmt = Actions.ActOnNullStmt(SemiLoc);
1935 return ParseCXXCondition(InitStmt: nullptr, Loc, CK, MissingOK);
1936 }
1937
1938 ExprResult Expr = [&] {
1939 EnterExpressionEvaluationContext Eval(
1940 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
1941 /*LambdaContextDecl=*/nullptr,
1942 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
1943 /*ShouldEnter=*/CK == Sema::ConditionKind::ConstexprIf);
1944 // Parse the expression.
1945 return ParseExpression(); // expression
1946 }();
1947
1948 if (Expr.isInvalid())
1949 return Sema::ConditionError();
1950
1951 if (InitStmt && Tok.is(K: tok::semi)) {
1952 WarnOnInit();
1953 *InitStmt = Actions.ActOnExprStmt(Arg: Expr.get());
1954 ConsumeToken();
1955 return ParseCXXCondition(InitStmt: nullptr, Loc, CK, MissingOK);
1956 }
1957
1958 return Actions.ActOnCondition(S: getCurScope(), Loc, SubExpr: Expr.get(), CK,
1959 MissingOK);
1960 }
1961
1962 case ConditionOrInitStatement::InitStmtDecl: {
1963 WarnOnInit();
1964 DeclGroupPtrTy DG;
1965 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1966 if (Tok.is(K: tok::kw_using))
1967 DG = ParseAliasDeclarationInInitStatement(
1968 Context: DeclaratorContext::SelectionInit, Attrs&: attrs);
1969 else {
1970 ParsedAttributes DeclSpecAttrs(AttrFactory);
1971 DG = ParseSimpleDeclaration(Context: DeclaratorContext::SelectionInit, DeclEnd,
1972 DeclAttrs&: attrs, DeclSpecAttrs, /*RequireSemi=*/true);
1973 }
1974 *InitStmt = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: DeclEnd);
1975 return ParseCXXCondition(InitStmt: nullptr, Loc, CK, MissingOK);
1976 }
1977
1978 case ConditionOrInitStatement::ForRangeDecl: {
1979 // This is 'for (init-stmt; for-range-decl : range-expr)'.
1980 // We're not actually in a for loop yet, so 'break' and 'continue' aren't
1981 // permitted here.
1982 assert(FRI && "should not parse a for range declaration here");
1983 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1984 ParsedAttributes DeclSpecAttrs(AttrFactory);
1985 DeclGroupPtrTy DG = ParseSimpleDeclaration(
1986 Context: DeclaratorContext::ForInit, DeclEnd, DeclAttrs&: attrs, DeclSpecAttrs, RequireSemi: false, FRI);
1987 FRI->LoopVar = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: Tok.getLocation());
1988 return Sema::ConditionResult();
1989 }
1990
1991 case ConditionOrInitStatement::ConditionDecl:
1992 case ConditionOrInitStatement::Error:
1993 break;
1994 }
1995
1996 // If this is a for loop, we're entering its condition.
1997 ForConditionScope.enter(/*IsConditionVariable=*/true);
1998
1999 // type-specifier-seq
2000 DeclSpec DS(AttrFactory);
2001 ParseSpecifierQualifierList(DS, AS: AS_none, DSC: DeclSpecContext::DSC_condition);
2002
2003 // declarator
2004 Declarator DeclaratorInfo(DS, attrs, DeclaratorContext::Condition);
2005 ParseDeclarator(D&: DeclaratorInfo);
2006
2007 // simple-asm-expr[opt]
2008 if (Tok.is(K: tok::kw_asm)) {
2009 SourceLocation Loc;
2010 ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, EndLoc: &Loc));
2011 if (AsmLabel.isInvalid()) {
2012 SkipUntil(T: tok::semi, Flags: StopAtSemi);
2013 return Sema::ConditionError();
2014 }
2015 DeclaratorInfo.setAsmLabel(AsmLabel.get());
2016 DeclaratorInfo.SetRangeEnd(Loc);
2017 }
2018
2019 // If attributes are present, parse them.
2020 MaybeParseGNUAttributes(D&: DeclaratorInfo);
2021
2022 // Type-check the declaration itself.
2023 DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(S: getCurScope(),
2024 D&: DeclaratorInfo);
2025 if (Dcl.isInvalid())
2026 return Sema::ConditionError();
2027 Decl *DeclOut = Dcl.get();
2028
2029 // '=' assignment-expression
2030 // If a '==' or '+=' is found, suggest a fixit to '='.
2031 bool CopyInitialization = isTokenEqualOrEqualTypo();
2032 if (CopyInitialization)
2033 ConsumeToken();
2034
2035 ExprResult InitExpr = ExprError();
2036 if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace)) {
2037 Diag(Tok.getLocation(),
2038 diag::warn_cxx98_compat_generalized_initializer_lists);
2039 InitExpr = ParseBraceInitializer();
2040 } else if (CopyInitialization) {
2041 PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);
2042 InitExpr = ParseAssignmentExpression();
2043 } else if (Tok.is(K: tok::l_paren)) {
2044 // This was probably an attempt to initialize the variable.
2045 SourceLocation LParen = ConsumeParen(), RParen = LParen;
2046 if (SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch))
2047 RParen = ConsumeParen();
2048 Diag(DeclOut->getLocation(),
2049 diag::err_expected_init_in_condition_lparen)
2050 << SourceRange(LParen, RParen);
2051 } else {
2052 Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);
2053 }
2054
2055 if (!InitExpr.isInvalid())
2056 Actions.AddInitializerToDecl(dcl: DeclOut, init: InitExpr.get(), DirectInit: !CopyInitialization);
2057 else
2058 Actions.ActOnInitializerError(Dcl: DeclOut);
2059
2060 Actions.FinalizeDeclaration(D: DeclOut);
2061 return Actions.ActOnConditionVariable(ConditionVar: DeclOut, StmtLoc: Loc, CK);
2062}
2063
2064void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
2065 DS.SetRangeStart(Tok.getLocation());
2066 const char *PrevSpec;
2067 unsigned DiagID;
2068 SourceLocation Loc = Tok.getLocation();
2069 const clang::PrintingPolicy &Policy =
2070 Actions.getASTContext().getPrintingPolicy();
2071
2072 switch (Tok.getKind()) {
2073 case tok::identifier: // foo::bar
2074 case tok::coloncolon: // ::foo::bar
2075 llvm_unreachable("Annotation token should already be formed!");
2076 default:
2077 llvm_unreachable("Not a simple-type-specifier token!");
2078
2079 // type-name
2080 case tok::annot_typename: {
2081 DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
2082 Rep: getTypeAnnotation(Tok), Policy);
2083 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2084 ConsumeAnnotationToken();
2085 DS.Finish(S&: Actions, Policy);
2086 return;
2087 }
2088
2089 case tok::kw__ExtInt:
2090 case tok::kw__BitInt: {
2091 DiagnoseBitIntUse(Tok);
2092 ExprResult ER = ParseExtIntegerArgument();
2093 if (ER.isInvalid())
2094 DS.SetTypeSpecError();
2095 else
2096 DS.SetBitIntType(KWLoc: Loc, BitWidth: ER.get(), PrevSpec, DiagID, Policy);
2097
2098 // Do this here because we have already consumed the close paren.
2099 DS.SetRangeEnd(PrevTokLocation);
2100 DS.Finish(S&: Actions, Policy);
2101 return;
2102 }
2103
2104 // builtin types
2105 case tok::kw_short:
2106 DS.SetTypeSpecWidth(W: TypeSpecifierWidth::Short, Loc, PrevSpec, DiagID,
2107 Policy);
2108 break;
2109 case tok::kw_long:
2110 DS.SetTypeSpecWidth(W: TypeSpecifierWidth::Long, Loc, PrevSpec, DiagID,
2111 Policy);
2112 break;
2113 case tok::kw___int64:
2114 DS.SetTypeSpecWidth(W: TypeSpecifierWidth::LongLong, Loc, PrevSpec, DiagID,
2115 Policy);
2116 break;
2117 case tok::kw_signed:
2118 DS.SetTypeSpecSign(S: TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID);
2119 break;
2120 case tok::kw_unsigned:
2121 DS.SetTypeSpecSign(S: TypeSpecifierSign::Unsigned, Loc, PrevSpec, DiagID);
2122 break;
2123 case tok::kw_void:
2124 DS.SetTypeSpecType(T: DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy);
2125 break;
2126 case tok::kw_auto:
2127 DS.SetTypeSpecType(T: DeclSpec::TST_auto, Loc, PrevSpec, DiagID, Policy);
2128 break;
2129 case tok::kw_char:
2130 DS.SetTypeSpecType(T: DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy);
2131 break;
2132 case tok::kw_int:
2133 DS.SetTypeSpecType(T: DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy);
2134 break;
2135 case tok::kw___int128:
2136 DS.SetTypeSpecType(T: DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
2137 break;
2138 case tok::kw___bf16:
2139 DS.SetTypeSpecType(T: DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy);
2140 break;
2141 case tok::kw_half:
2142 DS.SetTypeSpecType(T: DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy);
2143 break;
2144 case tok::kw_float:
2145 DS.SetTypeSpecType(T: DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy);
2146 break;
2147 case tok::kw_double:
2148 DS.SetTypeSpecType(T: DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);
2149 break;
2150 case tok::kw__Float16:
2151 DS.SetTypeSpecType(T: DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy);
2152 break;
2153 case tok::kw___float128:
2154 DS.SetTypeSpecType(T: DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);
2155 break;
2156 case tok::kw___ibm128:
2157 DS.SetTypeSpecType(T: DeclSpec::TST_ibm128, Loc, PrevSpec, DiagID, Policy);
2158 break;
2159 case tok::kw_wchar_t:
2160 DS.SetTypeSpecType(T: DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
2161 break;
2162 case tok::kw_char8_t:
2163 DS.SetTypeSpecType(T: DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy);
2164 break;
2165 case tok::kw_char16_t:
2166 DS.SetTypeSpecType(T: DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);
2167 break;
2168 case tok::kw_char32_t:
2169 DS.SetTypeSpecType(T: DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy);
2170 break;
2171 case tok::kw_bool:
2172 DS.SetTypeSpecType(T: DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
2173 break;
2174 case tok::kw__Accum:
2175 DS.SetTypeSpecType(T: DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy);
2176 break;
2177 case tok::kw__Fract:
2178 DS.SetTypeSpecType(T: DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy);
2179 break;
2180 case tok::kw__Sat:
2181 DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
2182 break;
2183#define GENERIC_IMAGE_TYPE(ImgType, Id) \
2184 case tok::kw_##ImgType##_t: \
2185 DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \
2186 Policy); \
2187 break;
2188#include "clang/Basic/OpenCLImageTypes.def"
2189#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2190 case tok::kw_##Name: \
2191 DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, DiagID, Policy); \
2192 break;
2193#include "clang/Basic/HLSLIntangibleTypes.def"
2194
2195 case tok::annot_decltype:
2196 case tok::kw_decltype:
2197 DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
2198 return DS.Finish(S&: Actions, Policy);
2199
2200 case tok::annot_pack_indexing_type:
2201 DS.SetRangeEnd(ParsePackIndexingType(DS));
2202 return DS.Finish(S&: Actions, Policy);
2203
2204 // GNU typeof support.
2205 case tok::kw_typeof:
2206 ParseTypeofSpecifier(DS);
2207 DS.Finish(S&: Actions, Policy);
2208 return;
2209 }
2210 ConsumeAnyToken();
2211 DS.SetRangeEnd(PrevTokLocation);
2212 DS.Finish(S&: Actions, Policy);
2213}
2214
2215bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS, DeclaratorContext Context) {
2216 ParseSpecifierQualifierList(DS, AS: AS_none,
2217 DSC: getDeclSpecContextFromDeclaratorContext(Context));
2218 DS.Finish(S&: Actions, Policy: Actions.getASTContext().getPrintingPolicy());
2219 return false;
2220}
2221
2222bool Parser::ParseUnqualifiedIdTemplateId(
2223 CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,
2224 SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc,
2225 bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId) {
2226 assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
2227
2228 TemplateTy Template;
2229 TemplateNameKind TNK = TNK_Non_template;
2230 switch (Id.getKind()) {
2231 case UnqualifiedIdKind::IK_Identifier:
2232 case UnqualifiedIdKind::IK_OperatorFunctionId:
2233 case UnqualifiedIdKind::IK_LiteralOperatorId:
2234 if (AssumeTemplateId) {
2235 // We defer the injected-class-name checks until we've found whether
2236 // this template-id is used to form a nested-name-specifier or not.
2237 TNK = Actions.ActOnTemplateName(S: getCurScope(), SS, TemplateKWLoc, Name: Id,
2238 ObjectType, EnteringContext, Template,
2239 /*AllowInjectedClassName*/ true);
2240 } else {
2241 bool MemberOfUnknownSpecialization;
2242 TNK = Actions.isTemplateName(S: getCurScope(), SS,
2243 hasTemplateKeyword: TemplateKWLoc.isValid(), Name: Id,
2244 ObjectType, EnteringContext, Template,
2245 MemberOfUnknownSpecialization);
2246 // If lookup found nothing but we're assuming that this is a template
2247 // name, double-check that makes sense syntactically before committing
2248 // to it.
2249 if (TNK == TNK_Undeclared_template &&
2250 isTemplateArgumentList(TokensToSkip: 0) == TPResult::False)
2251 return false;
2252
2253 if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&
2254 ObjectType && isTemplateArgumentList(TokensToSkip: 0) == TPResult::True) {
2255 // If we had errors before, ObjectType can be dependent even without any
2256 // templates, do not report missing template keyword in that case.
2257 if (!ObjectHadErrors) {
2258 // We have something like t->getAs<T>(), where getAs is a
2259 // member of an unknown specialization. However, this will only
2260 // parse correctly as a template, so suggest the keyword 'template'
2261 // before 'getAs' and treat this as a dependent template name.
2262 std::string Name;
2263 if (Id.getKind() == UnqualifiedIdKind::IK_Identifier)
2264 Name = std::string(Id.Identifier->getName());
2265 else {
2266 Name = "operator ";
2267 if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId)
2268 Name += getOperatorSpelling(Operator: Id.OperatorFunctionId.Operator);
2269 else
2270 Name += Id.Identifier->getName();
2271 }
2272 Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
2273 << Name
2274 << FixItHint::CreateInsertion(Id.StartLocation, "template ");
2275 }
2276 TNK = Actions.ActOnTemplateName(
2277 S: getCurScope(), SS, TemplateKWLoc, Name: Id, ObjectType, EnteringContext,
2278 Template, /*AllowInjectedClassName*/ true);
2279 } else if (TNK == TNK_Non_template) {
2280 return false;
2281 }
2282 }
2283 break;
2284
2285 case UnqualifiedIdKind::IK_ConstructorName: {
2286 UnqualifiedId TemplateName;
2287 bool MemberOfUnknownSpecialization;
2288 TemplateName.setIdentifier(Id: Name, IdLoc: NameLoc);
2289 TNK = Actions.isTemplateName(S: getCurScope(), SS, hasTemplateKeyword: TemplateKWLoc.isValid(),
2290 Name: TemplateName, ObjectType,
2291 EnteringContext, Template,
2292 MemberOfUnknownSpecialization);
2293 if (TNK == TNK_Non_template)
2294 return false;
2295 break;
2296 }
2297
2298 case UnqualifiedIdKind::IK_DestructorName: {
2299 UnqualifiedId TemplateName;
2300 bool MemberOfUnknownSpecialization;
2301 TemplateName.setIdentifier(Id: Name, IdLoc: NameLoc);
2302 if (ObjectType) {
2303 TNK = Actions.ActOnTemplateName(
2304 S: getCurScope(), SS, TemplateKWLoc, Name: TemplateName, ObjectType,
2305 EnteringContext, Template, /*AllowInjectedClassName*/ true);
2306 } else {
2307 TNK = Actions.isTemplateName(S: getCurScope(), SS, hasTemplateKeyword: TemplateKWLoc.isValid(),
2308 Name: TemplateName, ObjectType,
2309 EnteringContext, Template,
2310 MemberOfUnknownSpecialization);
2311
2312 if (TNK == TNK_Non_template && !Id.DestructorName.get()) {
2313 Diag(NameLoc, diag::err_destructor_template_id)
2314 << Name << SS.getRange();
2315 // Carry on to parse the template arguments before bailing out.
2316 }
2317 }
2318 break;
2319 }
2320
2321 default:
2322 return false;
2323 }
2324
2325 // Parse the enclosed template argument list.
2326 SourceLocation LAngleLoc, RAngleLoc;
2327 TemplateArgList TemplateArgs;
2328 if (ParseTemplateIdAfterTemplateName(ConsumeLastToken: true, LAngleLoc, TemplateArgs, RAngleLoc,
2329 NameHint: Template))
2330 return true;
2331
2332 // If this is a non-template, we already issued a diagnostic.
2333 if (TNK == TNK_Non_template)
2334 return true;
2335
2336 if (Id.getKind() == UnqualifiedIdKind::IK_Identifier ||
2337 Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
2338 Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) {
2339 // Form a parsed representation of the template-id to be stored in the
2340 // UnqualifiedId.
2341
2342 // FIXME: Store name for literal operator too.
2343 const IdentifierInfo *TemplateII =
2344 Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier
2345 : nullptr;
2346 OverloadedOperatorKind OpKind =
2347 Id.getKind() == UnqualifiedIdKind::IK_Identifier
2348 ? OO_None
2349 : Id.OperatorFunctionId.Operator;
2350
2351 TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
2352 TemplateKWLoc, TemplateNameLoc: Id.StartLocation, Name: TemplateII, OperatorKind: OpKind, OpaqueTemplateName: Template, TemplateKind: TNK,
2353 LAngleLoc, RAngleLoc, TemplateArgs, /*ArgsInvalid*/false, CleanupList&: TemplateIds);
2354
2355 Id.setTemplateId(TemplateId);
2356 return false;
2357 }
2358
2359 // Bundle the template arguments together.
2360 ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);
2361
2362 // Constructor and destructor names.
2363 TypeResult Type = Actions.ActOnTemplateIdType(
2364 S: getCurScope(), SS, TemplateKWLoc, Template, TemplateII: Name, TemplateIILoc: NameLoc, LAngleLoc,
2365 TemplateArgs: TemplateArgsPtr, RAngleLoc, /*IsCtorOrDtorName=*/true);
2366 if (Type.isInvalid())
2367 return true;
2368
2369 if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)
2370 Id.setConstructorName(ClassType: Type.get(), ClassNameLoc: NameLoc, EndLoc: RAngleLoc);
2371 else
2372 Id.setDestructorName(TildeLoc: Id.StartLocation, ClassType: Type.get(), EndLoc: RAngleLoc);
2373
2374 return false;
2375}
2376
2377bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
2378 ParsedType ObjectType,
2379 UnqualifiedId &Result) {
2380 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
2381
2382 // Consume the 'operator' keyword.
2383 SourceLocation KeywordLoc = ConsumeToken();
2384
2385 // Determine what kind of operator name we have.
2386 unsigned SymbolIdx = 0;
2387 SourceLocation SymbolLocations[3];
2388 OverloadedOperatorKind Op = OO_None;
2389 switch (Tok.getKind()) {
2390 case tok::kw_new:
2391 case tok::kw_delete: {
2392 bool isNew = Tok.getKind() == tok::kw_new;
2393 // Consume the 'new' or 'delete'.
2394 SymbolLocations[SymbolIdx++] = ConsumeToken();
2395 // Check for array new/delete.
2396 if (Tok.is(K: tok::l_square) &&
2397 (!getLangOpts().CPlusPlus11 || NextToken().isNot(K: tok::l_square))) {
2398 // Consume the '[' and ']'.
2399 BalancedDelimiterTracker T(*this, tok::l_square);
2400 T.consumeOpen();
2401 T.consumeClose();
2402 if (T.getCloseLocation().isInvalid())
2403 return true;
2404
2405 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2406 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2407 Op = isNew? OO_Array_New : OO_Array_Delete;
2408 } else {
2409 Op = isNew? OO_New : OO_Delete;
2410 }
2411 break;
2412 }
2413
2414#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2415 case tok::Token: \
2416 SymbolLocations[SymbolIdx++] = ConsumeToken(); \
2417 Op = OO_##Name; \
2418 break;
2419#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2420#include "clang/Basic/OperatorKinds.def"
2421
2422 case tok::l_paren: {
2423 // Consume the '(' and ')'.
2424 BalancedDelimiterTracker T(*this, tok::l_paren);
2425 T.consumeOpen();
2426 T.consumeClose();
2427 if (T.getCloseLocation().isInvalid())
2428 return true;
2429
2430 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2431 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2432 Op = OO_Call;
2433 break;
2434 }
2435
2436 case tok::l_square: {
2437 // Consume the '[' and ']'.
2438 BalancedDelimiterTracker T(*this, tok::l_square);
2439 T.consumeOpen();
2440 T.consumeClose();
2441 if (T.getCloseLocation().isInvalid())
2442 return true;
2443
2444 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2445 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2446 Op = OO_Subscript;
2447 break;
2448 }
2449
2450 case tok::code_completion: {
2451 // Don't try to parse any further.
2452 cutOffParsing();
2453 // Code completion for the operator name.
2454 Actions.CodeCompletion().CodeCompleteOperatorName(S: getCurScope());
2455 return true;
2456 }
2457
2458 default:
2459 break;
2460 }
2461
2462 if (Op != OO_None) {
2463 // We have parsed an operator-function-id.
2464 Result.setOperatorFunctionId(OperatorLoc: KeywordLoc, Op, SymbolLocations);
2465 return false;
2466 }
2467
2468 // Parse a literal-operator-id.
2469 //
2470 // literal-operator-id: C++11 [over.literal]
2471 // operator string-literal identifier
2472 // operator user-defined-string-literal
2473
2474 if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
2475 Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
2476
2477 SourceLocation DiagLoc;
2478 unsigned DiagId = 0;
2479
2480 // We're past translation phase 6, so perform string literal concatenation
2481 // before checking for "".
2482 SmallVector<Token, 4> Toks;
2483 SmallVector<SourceLocation, 4> TokLocs;
2484 while (isTokenStringLiteral()) {
2485 if (!Tok.is(K: tok::string_literal) && !DiagId) {
2486 // C++11 [over.literal]p1:
2487 // The string-literal or user-defined-string-literal in a
2488 // literal-operator-id shall have no encoding-prefix [...].
2489 DiagLoc = Tok.getLocation();
2490 DiagId = diag::err_literal_operator_string_prefix;
2491 }
2492 Toks.push_back(Elt: Tok);
2493 TokLocs.push_back(Elt: ConsumeStringToken());
2494 }
2495
2496 StringLiteralParser Literal(Toks, PP);
2497 if (Literal.hadError)
2498 return true;
2499
2500 // Grab the literal operator's suffix, which will be either the next token
2501 // or a ud-suffix from the string literal.
2502 bool IsUDSuffix = !Literal.getUDSuffix().empty();
2503 IdentifierInfo *II = nullptr;
2504 SourceLocation SuffixLoc;
2505 if (IsUDSuffix) {
2506 II = &PP.getIdentifierTable().get(Name: Literal.getUDSuffix());
2507 SuffixLoc =
2508 Lexer::AdvanceToTokenCharacter(TokStart: TokLocs[Literal.getUDSuffixToken()],
2509 Characters: Literal.getUDSuffixOffset(),
2510 SM: PP.getSourceManager(), LangOpts: getLangOpts());
2511 } else if (Tok.is(K: tok::identifier)) {
2512 II = Tok.getIdentifierInfo();
2513 SuffixLoc = ConsumeToken();
2514 TokLocs.push_back(Elt: SuffixLoc);
2515 } else {
2516 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
2517 return true;
2518 }
2519
2520 // The string literal must be empty.
2521 if (!Literal.GetString().empty() || Literal.Pascal) {
2522 // C++11 [over.literal]p1:
2523 // The string-literal or user-defined-string-literal in a
2524 // literal-operator-id shall [...] contain no characters
2525 // other than the implicit terminating '\0'.
2526 DiagLoc = TokLocs.front();
2527 DiagId = diag::err_literal_operator_string_not_empty;
2528 }
2529
2530 if (DiagId) {
2531 // This isn't a valid literal-operator-id, but we think we know
2532 // what the user meant. Tell them what they should have written.
2533 SmallString<32> Str;
2534 Str += "\"\"";
2535 Str += II->getName();
2536 Diag(Loc: DiagLoc, DiagID: DiagId) << FixItHint::CreateReplacement(
2537 RemoveRange: SourceRange(TokLocs.front(), TokLocs.back()), Code: Str);
2538 }
2539
2540 Result.setLiteralOperatorId(Id: II, OpLoc: KeywordLoc, IdLoc: SuffixLoc);
2541
2542 return Actions.checkLiteralOperatorId(SS, Id: Result, IsUDSuffix);
2543 }
2544
2545 // Parse a conversion-function-id.
2546 //
2547 // conversion-function-id: [C++ 12.3.2]
2548 // operator conversion-type-id
2549 //
2550 // conversion-type-id:
2551 // type-specifier-seq conversion-declarator[opt]
2552 //
2553 // conversion-declarator:
2554 // ptr-operator conversion-declarator[opt]
2555
2556 // Parse the type-specifier-seq.
2557 DeclSpec DS(AttrFactory);
2558 if (ParseCXXTypeSpecifierSeq(
2559 DS, Context: DeclaratorContext::ConversionId)) // FIXME: ObjectType?
2560 return true;
2561
2562 // Parse the conversion-declarator, which is merely a sequence of
2563 // ptr-operators.
2564 Declarator D(DS, ParsedAttributesView::none(),
2565 DeclaratorContext::ConversionId);
2566 ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);
2567
2568 // Finish up the type.
2569 TypeResult Ty = Actions.ActOnTypeName(D);
2570 if (Ty.isInvalid())
2571 return true;
2572
2573 // Note that this is a conversion-function-id.
2574 Result.setConversionFunctionId(OperatorLoc: KeywordLoc, Ty: Ty.get(),
2575 EndLoc: D.getSourceRange().getEnd());
2576 return false;
2577}
2578
2579bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
2580 bool ObjectHadErrors, bool EnteringContext,
2581 bool AllowDestructorName,
2582 bool AllowConstructorName,
2583 bool AllowDeductionGuide,
2584 SourceLocation *TemplateKWLoc,
2585 UnqualifiedId &Result) {
2586 if (TemplateKWLoc)
2587 *TemplateKWLoc = SourceLocation();
2588
2589 // Handle 'A::template B'. This is for template-ids which have not
2590 // already been annotated by ParseOptionalCXXScopeSpecifier().
2591 bool TemplateSpecified = false;
2592 if (Tok.is(K: tok::kw_template)) {
2593 if (TemplateKWLoc && (ObjectType || SS.isSet())) {
2594 TemplateSpecified = true;
2595 *TemplateKWLoc = ConsumeToken();
2596 } else {
2597 SourceLocation TemplateLoc = ConsumeToken();
2598 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
2599 << FixItHint::CreateRemoval(TemplateLoc);
2600 }
2601 }
2602
2603 // unqualified-id:
2604 // identifier
2605 // template-id (when it hasn't already been annotated)
2606 if (Tok.is(K: tok::identifier)) {
2607 ParseIdentifier:
2608 // Consume the identifier.
2609 IdentifierInfo *Id = Tok.getIdentifierInfo();
2610 SourceLocation IdLoc = ConsumeToken();
2611
2612 if (!getLangOpts().CPlusPlus) {
2613 // If we're not in C++, only identifiers matter. Record the
2614 // identifier and return.
2615 Result.setIdentifier(Id, IdLoc);
2616 return false;
2617 }
2618
2619 ParsedTemplateTy TemplateName;
2620 if (AllowConstructorName &&
2621 Actions.isCurrentClassName(II: *Id, S: getCurScope(), SS: &SS)) {
2622 // We have parsed a constructor name.
2623 ParsedType Ty = Actions.getConstructorName(II: *Id, NameLoc: IdLoc, S: getCurScope(), SS,
2624 EnteringContext);
2625 if (!Ty)
2626 return true;
2627 Result.setConstructorName(ClassType: Ty, ClassNameLoc: IdLoc, EndLoc: IdLoc);
2628 } else if (getLangOpts().CPlusPlus17 && AllowDeductionGuide &&
2629 SS.isEmpty() &&
2630 Actions.isDeductionGuideName(S: getCurScope(), Name: *Id, NameLoc: IdLoc, SS,
2631 Template: &TemplateName)) {
2632 // We have parsed a template-name naming a deduction guide.
2633 Result.setDeductionGuideName(Template: TemplateName, TemplateLoc: IdLoc);
2634 } else {
2635 // We have parsed an identifier.
2636 Result.setIdentifier(Id, IdLoc);
2637 }
2638
2639 // If the next token is a '<', we may have a template.
2640 TemplateTy Template;
2641 if (Tok.is(K: tok::less))
2642 return ParseUnqualifiedIdTemplateId(
2643 SS, ObjectType, ObjectHadErrors,
2644 TemplateKWLoc: TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Name: Id, NameLoc: IdLoc,
2645 EnteringContext, Id&: Result, AssumeTemplateId: TemplateSpecified);
2646
2647 if (TemplateSpecified) {
2648 TemplateNameKind TNK =
2649 Actions.ActOnTemplateName(S: getCurScope(), SS, TemplateKWLoc: *TemplateKWLoc, Name: Result,
2650 ObjectType, EnteringContext, Template,
2651 /*AllowInjectedClassName=*/true);
2652 if (TNK == TNK_Non_template)
2653 return true;
2654
2655 // C++2c [tem.names]p6
2656 // A name prefixed by the keyword template shall be followed by a template
2657 // argument list or refer to a class template or an alias template.
2658 if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||
2659 TNK == TNK_Var_template) &&
2660 !Tok.is(tok::less))
2661 Diag(IdLoc, diag::missing_template_arg_list_after_template_kw);
2662 }
2663 return false;
2664 }
2665
2666 // unqualified-id:
2667 // template-id (already parsed and annotated)
2668 if (Tok.is(K: tok::annot_template_id)) {
2669 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok);
2670
2671 // FIXME: Consider passing invalid template-ids on to callers; they may
2672 // be able to recover better than we can.
2673 if (TemplateId->isInvalid()) {
2674 ConsumeAnnotationToken();
2675 return true;
2676 }
2677
2678 // If the template-name names the current class, then this is a constructor
2679 if (AllowConstructorName && TemplateId->Name &&
2680 Actions.isCurrentClassName(II: *TemplateId->Name, S: getCurScope(), SS: &SS)) {
2681 if (SS.isSet()) {
2682 // C++ [class.qual]p2 specifies that a qualified template-name
2683 // is taken as the constructor name where a constructor can be
2684 // declared. Thus, the template arguments are extraneous, so
2685 // complain about them and remove them entirely.
2686 Diag(TemplateId->TemplateNameLoc,
2687 diag::err_out_of_line_constructor_template_id)
2688 << TemplateId->Name
2689 << FixItHint::CreateRemoval(
2690 SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
2691 ParsedType Ty = Actions.getConstructorName(
2692 II: *TemplateId->Name, NameLoc: TemplateId->TemplateNameLoc, S: getCurScope(), SS,
2693 EnteringContext);
2694 if (!Ty)
2695 return true;
2696 Result.setConstructorName(ClassType: Ty, ClassNameLoc: TemplateId->TemplateNameLoc,
2697 EndLoc: TemplateId->RAngleLoc);
2698 ConsumeAnnotationToken();
2699 return false;
2700 }
2701
2702 Result.setConstructorTemplateId(TemplateId);
2703 ConsumeAnnotationToken();
2704 return false;
2705 }
2706
2707 // We have already parsed a template-id; consume the annotation token as
2708 // our unqualified-id.
2709 Result.setTemplateId(TemplateId);
2710 SourceLocation TemplateLoc = TemplateId->TemplateKWLoc;
2711 if (TemplateLoc.isValid()) {
2712 if (TemplateKWLoc && (ObjectType || SS.isSet()))
2713 *TemplateKWLoc = TemplateLoc;
2714 else
2715 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
2716 << FixItHint::CreateRemoval(TemplateLoc);
2717 }
2718 ConsumeAnnotationToken();
2719 return false;
2720 }
2721
2722 // unqualified-id:
2723 // operator-function-id
2724 // conversion-function-id
2725 if (Tok.is(K: tok::kw_operator)) {
2726 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
2727 return true;
2728
2729 // If we have an operator-function-id or a literal-operator-id and the next
2730 // token is a '<', we may have a
2731 //
2732 // template-id:
2733 // operator-function-id < template-argument-list[opt] >
2734 TemplateTy Template;
2735 if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
2736 Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) &&
2737 Tok.is(K: tok::less))
2738 return ParseUnqualifiedIdTemplateId(
2739 SS, ObjectType, ObjectHadErrors,
2740 TemplateKWLoc: TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Name: nullptr,
2741 NameLoc: SourceLocation(), EnteringContext, Id&: Result, AssumeTemplateId: TemplateSpecified);
2742 else if (TemplateSpecified &&
2743 Actions.ActOnTemplateName(
2744 S: getCurScope(), SS, TemplateKWLoc: *TemplateKWLoc, Name: Result, ObjectType,
2745 EnteringContext, Template,
2746 /*AllowInjectedClassName*/ true) == TNK_Non_template)
2747 return true;
2748
2749 return false;
2750 }
2751
2752 if (getLangOpts().CPlusPlus &&
2753 (AllowDestructorName || SS.isSet()) && Tok.is(K: tok::tilde)) {
2754 // C++ [expr.unary.op]p10:
2755 // There is an ambiguity in the unary-expression ~X(), where X is a
2756 // class-name. The ambiguity is resolved in favor of treating ~ as a
2757 // unary complement rather than treating ~X as referring to a destructor.
2758
2759 // Parse the '~'.
2760 SourceLocation TildeLoc = ConsumeToken();
2761
2762 if (TemplateSpecified) {
2763 // C++ [temp.names]p3:
2764 // A name prefixed by the keyword template shall be a template-id [...]
2765 //
2766 // A template-id cannot begin with a '~' token. This would never work
2767 // anyway: x.~A<int>() would specify that the destructor is a template,
2768 // not that 'A' is a template.
2769 //
2770 // FIXME: Suggest replacing the attempted destructor name with a correct
2771 // destructor name and recover. (This is not trivial if this would become
2772 // a pseudo-destructor name).
2773 Diag(*TemplateKWLoc, diag::err_unexpected_template_in_destructor_name)
2774 << Tok.getLocation();
2775 return true;
2776 }
2777
2778 if (SS.isEmpty() && Tok.is(K: tok::kw_decltype)) {
2779 DeclSpec DS(AttrFactory);
2780 SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
2781 if (ParsedType Type =
2782 Actions.getDestructorTypeForDecltype(DS, ObjectType)) {
2783 Result.setDestructorName(TildeLoc, ClassType: Type, EndLoc);
2784 return false;
2785 }
2786 return true;
2787 }
2788
2789 // Parse the class-name.
2790 if (Tok.isNot(K: tok::identifier)) {
2791 Diag(Tok, diag::err_destructor_tilde_identifier);
2792 return true;
2793 }
2794
2795 // If the user wrote ~T::T, correct it to T::~T.
2796 DeclaratorScopeObj DeclScopeObj(*this, SS);
2797 if (NextToken().is(K: tok::coloncolon)) {
2798 // Don't let ParseOptionalCXXScopeSpecifier() "correct"
2799 // `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`,
2800 // it will confuse this recovery logic.
2801 ColonProtectionRAIIObject ColonRAII(*this, false);
2802
2803 if (SS.isSet()) {
2804 AnnotateScopeToken(SS, /*NewAnnotation*/IsNewAnnotation: true);
2805 SS.clear();
2806 }
2807 if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, ObjectHadErrors,
2808 EnteringContext))
2809 return true;
2810 if (SS.isNotEmpty())
2811 ObjectType = nullptr;
2812 if (Tok.isNot(K: tok::identifier) || NextToken().is(K: tok::coloncolon) ||
2813 !SS.isSet()) {
2814 Diag(TildeLoc, diag::err_destructor_tilde_scope);
2815 return true;
2816 }
2817
2818 // Recover as if the tilde had been written before the identifier.
2819 Diag(TildeLoc, diag::err_destructor_tilde_scope)
2820 << FixItHint::CreateRemoval(TildeLoc)
2821 << FixItHint::CreateInsertion(Tok.getLocation(), "~");
2822
2823 // Temporarily enter the scope for the rest of this function.
2824 if (Actions.ShouldEnterDeclaratorScope(S: getCurScope(), SS))
2825 DeclScopeObj.EnterDeclaratorScope();
2826 }
2827
2828 // Parse the class-name (or template-name in a simple-template-id).
2829 IdentifierInfo *ClassName = Tok.getIdentifierInfo();
2830 SourceLocation ClassNameLoc = ConsumeToken();
2831
2832 if (Tok.is(K: tok::less)) {
2833 Result.setDestructorName(TildeLoc, ClassType: nullptr, EndLoc: ClassNameLoc);
2834 return ParseUnqualifiedIdTemplateId(
2835 SS, ObjectType, ObjectHadErrors,
2836 TemplateKWLoc: TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Name: ClassName,
2837 NameLoc: ClassNameLoc, EnteringContext, Id&: Result, AssumeTemplateId: TemplateSpecified);
2838 }
2839
2840 // Note that this is a destructor name.
2841 ParsedType Ty =
2842 Actions.getDestructorName(II: *ClassName, NameLoc: ClassNameLoc, S: getCurScope(), SS,
2843 ObjectType, EnteringContext);
2844 if (!Ty)
2845 return true;
2846
2847 Result.setDestructorName(TildeLoc, ClassType: Ty, EndLoc: ClassNameLoc);
2848 return false;
2849 }
2850
2851 switch (Tok.getKind()) {
2852#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
2853#include "clang/Basic/TransformTypeTraits.def"
2854 if (!NextToken().is(K: tok::l_paren)) {
2855 Tok.setKind(tok::identifier);
2856 Diag(Tok, diag::ext_keyword_as_ident)
2857 << Tok.getIdentifierInfo()->getName() << 0;
2858 goto ParseIdentifier;
2859 }
2860 [[fallthrough]];
2861 default:
2862 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
2863 return true;
2864 }
2865}
2866
2867ExprResult
2868Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
2869 assert(Tok.is(tok::kw_new) && "expected 'new' token");
2870 ConsumeToken(); // Consume 'new'
2871
2872 // A '(' now can be a new-placement or the '(' wrapping the type-id in the
2873 // second form of new-expression. It can't be a new-type-id.
2874
2875 ExprVector PlacementArgs;
2876 SourceLocation PlacementLParen, PlacementRParen;
2877
2878 SourceRange TypeIdParens;
2879 DeclSpec DS(AttrFactory);
2880 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
2881 DeclaratorContext::CXXNew);
2882 if (Tok.is(K: tok::l_paren)) {
2883 // If it turns out to be a placement, we change the type location.
2884 BalancedDelimiterTracker T(*this, tok::l_paren);
2885 T.consumeOpen();
2886 PlacementLParen = T.getOpenLocation();
2887 if (ParseExpressionListOrTypeId(Exprs&: PlacementArgs, D&: DeclaratorInfo)) {
2888 SkipUntil(T: tok::semi, Flags: StopAtSemi | StopBeforeMatch);
2889 return ExprError();
2890 }
2891
2892 T.consumeClose();
2893 PlacementRParen = T.getCloseLocation();
2894 if (PlacementRParen.isInvalid()) {
2895 SkipUntil(T: tok::semi, Flags: StopAtSemi | StopBeforeMatch);
2896 return ExprError();
2897 }
2898
2899 if (PlacementArgs.empty()) {
2900 // Reset the placement locations. There was no placement.
2901 TypeIdParens = T.getRange();
2902 PlacementLParen = PlacementRParen = SourceLocation();
2903 } else {
2904 // We still need the type.
2905 if (Tok.is(K: tok::l_paren)) {
2906 BalancedDelimiterTracker T(*this, tok::l_paren);
2907 T.consumeOpen();
2908 MaybeParseGNUAttributes(D&: DeclaratorInfo);
2909 ParseSpecifierQualifierList(DS);
2910 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2911 ParseDeclarator(D&: DeclaratorInfo);
2912 T.consumeClose();
2913 TypeIdParens = T.getRange();
2914 } else {
2915 MaybeParseGNUAttributes(D&: DeclaratorInfo);
2916 if (ParseCXXTypeSpecifierSeq(DS))
2917 DeclaratorInfo.setInvalidType(true);
2918 else {
2919 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2920 ParseDeclaratorInternal(D&: DeclaratorInfo,
2921 DirectDeclParser: &Parser::ParseDirectNewDeclarator);
2922 }
2923 }
2924 }
2925 } else {
2926 // A new-type-id is a simplified type-id, where essentially the
2927 // direct-declarator is replaced by a direct-new-declarator.
2928 MaybeParseGNUAttributes(D&: DeclaratorInfo);
2929 if (ParseCXXTypeSpecifierSeq(DS, Context: DeclaratorContext::CXXNew))
2930 DeclaratorInfo.setInvalidType(true);
2931 else {
2932 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2933 ParseDeclaratorInternal(D&: DeclaratorInfo,
2934 DirectDeclParser: &Parser::ParseDirectNewDeclarator);
2935 }
2936 }
2937 if (DeclaratorInfo.isInvalidType()) {
2938 SkipUntil(T: tok::semi, Flags: StopAtSemi | StopBeforeMatch);
2939 return ExprError();
2940 }
2941
2942 ExprResult Initializer;
2943
2944 if (Tok.is(K: tok::l_paren)) {
2945 SourceLocation ConstructorLParen, ConstructorRParen;
2946 ExprVector ConstructorArgs;
2947 BalancedDelimiterTracker T(*this, tok::l_paren);
2948 T.consumeOpen();
2949 ConstructorLParen = T.getOpenLocation();
2950 if (Tok.isNot(K: tok::r_paren)) {
2951 auto RunSignatureHelp = [&]() {
2952 ParsedType TypeRep = Actions.ActOnTypeName(D&: DeclaratorInfo).get();
2953 QualType PreferredType;
2954 // ActOnTypeName might adjust DeclaratorInfo and return a null type even
2955 // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on
2956 // `new decltype(invalid) (^)`.
2957 if (TypeRep)
2958 PreferredType =
2959 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2960 Type: TypeRep.get()->getCanonicalTypeInternal(),
2961 Loc: DeclaratorInfo.getEndLoc(), Args: ConstructorArgs,
2962 OpenParLoc: ConstructorLParen,
2963 /*Braced=*/false);
2964 CalledSignatureHelp = true;
2965 return PreferredType;
2966 };
2967 if (ParseExpressionList(Exprs&: ConstructorArgs, ExpressionStarts: [&] {
2968 PreferredType.enterFunctionArgument(Tok.getLocation(),
2969 RunSignatureHelp);
2970 })) {
2971 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
2972 RunSignatureHelp();
2973 SkipUntil(T: tok::semi, Flags: StopAtSemi | StopBeforeMatch);
2974 return ExprError();
2975 }
2976 }
2977 T.consumeClose();
2978 ConstructorRParen = T.getCloseLocation();
2979 if (ConstructorRParen.isInvalid()) {
2980 SkipUntil(T: tok::semi, Flags: StopAtSemi | StopBeforeMatch);
2981 return ExprError();
2982 }
2983 Initializer = Actions.ActOnParenListExpr(L: ConstructorLParen,
2984 R: ConstructorRParen,
2985 Val: ConstructorArgs);
2986 } else if (Tok.is(K: tok::l_brace) && getLangOpts().CPlusPlus11) {
2987 Diag(Tok.getLocation(),
2988 diag::warn_cxx98_compat_generalized_initializer_lists);
2989 Initializer = ParseBraceInitializer();
2990 }
2991 if (Initializer.isInvalid())
2992 return Initializer;
2993
2994 return Actions.ActOnCXXNew(StartLoc: Start, UseGlobal, PlacementLParen,
2995 PlacementArgs, PlacementRParen,
2996 TypeIdParens, D&: DeclaratorInfo, Initializer: Initializer.get());
2997}
2998
2999void Parser::ParseDirectNewDeclarator(Declarator &D) {
3000 // Parse the array dimensions.
3001 bool First = true;
3002 while (Tok.is(K: tok::l_square)) {
3003 // An array-size expression can't start with a lambda.
3004 if (CheckProhibitedCXX11Attribute())
3005 continue;
3006
3007 BalancedDelimiterTracker T(*this, tok::l_square);
3008 T.consumeOpen();
3009
3010 ExprResult Size =
3011 First ? (Tok.is(K: tok::r_square) ? ExprResult() : ParseExpression())
3012 : ParseConstantExpression();
3013 if (Size.isInvalid()) {
3014 // Recover
3015 SkipUntil(T: tok::r_square, Flags: StopAtSemi);
3016 return;
3017 }
3018 First = false;
3019
3020 T.consumeClose();
3021
3022 // Attributes here appertain to the array type. C++11 [expr.new]p5.
3023 ParsedAttributes Attrs(AttrFactory);
3024 MaybeParseCXX11Attributes(Attrs);
3025
3026 D.AddTypeInfo(TI: DeclaratorChunk::getArray(TypeQuals: 0,
3027 /*isStatic=*/false, /*isStar=*/false,
3028 NumElts: Size.get(), LBLoc: T.getOpenLocation(),
3029 RBLoc: T.getCloseLocation()),
3030 attrs: std::move(Attrs), EndLoc: T.getCloseLocation());
3031
3032 if (T.getCloseLocation().isInvalid())
3033 return;
3034 }
3035}
3036
3037bool Parser::ParseExpressionListOrTypeId(
3038 SmallVectorImpl<Expr*> &PlacementArgs,
3039 Declarator &D) {
3040 // The '(' was already consumed.
3041 if (isTypeIdInParens()) {
3042 ParseSpecifierQualifierList(DS&: D.getMutableDeclSpec());
3043 D.SetSourceRange(D.getDeclSpec().getSourceRange());
3044 ParseDeclarator(D);
3045 return D.isInvalidType();
3046 }
3047
3048 // It's not a type, it has to be an expression list.
3049 return ParseExpressionList(Exprs&: PlacementArgs);
3050}
3051
3052ExprResult
3053Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
3054 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
3055 ConsumeToken(); // Consume 'delete'
3056
3057 // Array delete?
3058 bool ArrayDelete = false;
3059 if (Tok.is(K: tok::l_square) && NextToken().is(K: tok::r_square)) {
3060 // C++11 [expr.delete]p1:
3061 // Whenever the delete keyword is followed by empty square brackets, it
3062 // shall be interpreted as [array delete].
3063 // [Footnote: A lambda expression with a lambda-introducer that consists
3064 // of empty square brackets can follow the delete keyword if
3065 // the lambda expression is enclosed in parentheses.]
3066
3067 const Token Next = GetLookAheadToken(N: 2);
3068
3069 // Basic lookahead to check if we have a lambda expression.
3070 if (Next.isOneOf(K1: tok::l_brace, K2: tok::less) ||
3071 (Next.is(K: tok::l_paren) &&
3072 (GetLookAheadToken(N: 3).is(K: tok::r_paren) ||
3073 (GetLookAheadToken(N: 3).is(K: tok::identifier) &&
3074 GetLookAheadToken(N: 4).is(K: tok::identifier))))) {
3075 TentativeParsingAction TPA(*this);
3076 SourceLocation LSquareLoc = Tok.getLocation();
3077 SourceLocation RSquareLoc = NextToken().getLocation();
3078
3079 // SkipUntil can't skip pairs of </*...*/>; don't emit a FixIt in this
3080 // case.
3081 SkipUntil(Toks: {tok::l_brace, tok::less}, Flags: StopBeforeMatch);
3082 SourceLocation RBraceLoc;
3083 bool EmitFixIt = false;
3084 if (Tok.is(K: tok::l_brace)) {
3085 ConsumeBrace();
3086 SkipUntil(T: tok::r_brace, Flags: StopBeforeMatch);
3087 RBraceLoc = Tok.getLocation();
3088 EmitFixIt = true;
3089 }
3090
3091 TPA.Revert();
3092
3093 if (EmitFixIt)
3094 Diag(Start, diag::err_lambda_after_delete)
3095 << SourceRange(Start, RSquareLoc)
3096 << FixItHint::CreateInsertion(LSquareLoc, "(")
3097 << FixItHint::CreateInsertion(
3098 Lexer::getLocForEndOfToken(
3099 RBraceLoc, 0, Actions.getSourceManager(), getLangOpts()),
3100 ")");
3101 else
3102 Diag(Start, diag::err_lambda_after_delete)
3103 << SourceRange(Start, RSquareLoc);
3104
3105 // Warn that the non-capturing lambda isn't surrounded by parentheses
3106 // to disambiguate it from 'delete[]'.
3107 ExprResult Lambda = ParseLambdaExpression();
3108 if (Lambda.isInvalid())
3109 return ExprError();
3110
3111 // Evaluate any postfix expressions used on the lambda.
3112 Lambda = ParsePostfixExpressionSuffix(LHS: Lambda);
3113 if (Lambda.isInvalid())
3114 return ExprError();
3115 return Actions.ActOnCXXDelete(StartLoc: Start, UseGlobal, /*ArrayForm=*/false,
3116 Operand: Lambda.get());
3117 }
3118
3119 ArrayDelete = true;
3120 BalancedDelimiterTracker T(*this, tok::l_square);
3121
3122 T.consumeOpen();
3123 T.consumeClose();
3124 if (T.getCloseLocation().isInvalid())
3125 return ExprError();
3126 }
3127
3128 ExprResult Operand(ParseCastExpression(ParseKind: CastParseKind::AnyCastExpr));
3129 if (Operand.isInvalid())
3130 return Operand;
3131
3132 return Actions.ActOnCXXDelete(StartLoc: Start, UseGlobal, ArrayForm: ArrayDelete, Operand: Operand.get());
3133}
3134
3135ExprResult Parser::ParseRequiresExpression() {
3136 assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");
3137 SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires'
3138
3139 llvm::SmallVector<ParmVarDecl *, 2> LocalParameterDecls;
3140 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3141 if (Tok.is(K: tok::l_paren)) {
3142 // requirement parameter list is present.
3143 ParseScope LocalParametersScope(this, Scope::FunctionPrototypeScope |
3144 Scope::DeclScope);
3145 Parens.consumeOpen();
3146 if (!Tok.is(K: tok::r_paren)) {
3147 ParsedAttributes FirstArgAttrs(getAttrFactory());
3148 SourceLocation EllipsisLoc;
3149 llvm::SmallVector<DeclaratorChunk::ParamInfo, 2> LocalParameters;
3150 ParseParameterDeclarationClause(DeclaratorContext: DeclaratorContext::RequiresExpr,
3151 attrs&: FirstArgAttrs, ParamInfo&: LocalParameters,
3152 EllipsisLoc);
3153 if (EllipsisLoc.isValid())
3154 Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis);
3155 for (auto &ParamInfo : LocalParameters)
3156 LocalParameterDecls.push_back(Elt: cast<ParmVarDecl>(Val: ParamInfo.Param));
3157 }
3158 Parens.consumeClose();
3159 }
3160
3161 BalancedDelimiterTracker Braces(*this, tok::l_brace);
3162 if (Braces.expectAndConsume())
3163 return ExprError();
3164
3165 // Start of requirement list
3166 llvm::SmallVector<concepts::Requirement *, 2> Requirements;
3167
3168 // C++2a [expr.prim.req]p2
3169 // Expressions appearing within a requirement-body are unevaluated operands.
3170 EnterExpressionEvaluationContext Ctx(
3171 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
3172
3173 ParseScope BodyScope(this, Scope::DeclScope);
3174 // Create a separate diagnostic pool for RequiresExprBodyDecl.
3175 // Dependent diagnostics are attached to this Decl and non-depenedent
3176 // diagnostics are surfaced after this parse.
3177 ParsingDeclRAIIObject ParsingBodyDecl(*this, ParsingDeclRAIIObject::NoParent);
3178 RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(
3179 RequiresKWLoc, LocalParameters: LocalParameterDecls, BodyScope: getCurScope());
3180
3181 if (Tok.is(K: tok::r_brace)) {
3182 // Grammar does not allow an empty body.
3183 // requirement-body:
3184 // { requirement-seq }
3185 // requirement-seq:
3186 // requirement
3187 // requirement-seq requirement
3188 Diag(Tok, diag::err_empty_requires_expr);
3189 // Continue anyway and produce a requires expr with no requirements.
3190 } else {
3191 while (!Tok.is(K: tok::r_brace)) {
3192 switch (Tok.getKind()) {
3193 case tok::l_brace: {
3194 // Compound requirement
3195 // C++ [expr.prim.req.compound]
3196 // compound-requirement:
3197 // '{' expression '}' 'noexcept'[opt]
3198 // return-type-requirement[opt] ';'
3199 // return-type-requirement:
3200 // trailing-return-type
3201 // '->' cv-qualifier-seq[opt] constrained-parameter
3202 // cv-qualifier-seq[opt] abstract-declarator[opt]
3203 BalancedDelimiterTracker ExprBraces(*this, tok::l_brace);
3204 ExprBraces.consumeOpen();
3205 ExprResult Expression =
3206 Actions.CorrectDelayedTyposInExpr(ER: ParseExpression());
3207 if (!Expression.isUsable()) {
3208 ExprBraces.skipToEnd();
3209 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3210 break;
3211 }
3212 // If there's an error consuming the closing bracket, consumeClose()
3213 // will handle skipping to the nearest recovery point for us.
3214 if (ExprBraces.consumeClose())
3215 break;
3216
3217 concepts::Requirement *Req = nullptr;
3218 SourceLocation NoexceptLoc;
3219 TryConsumeToken(Expected: tok::kw_noexcept, Loc&: NoexceptLoc);
3220 if (Tok.is(K: tok::semi)) {
3221 Req = Actions.ActOnCompoundRequirement(E: Expression.get(), NoexceptLoc);
3222 if (Req)
3223 Requirements.push_back(Elt: Req);
3224 break;
3225 }
3226 if (!TryConsumeToken(tok::arrow))
3227 // User probably forgot the arrow, remind them and try to continue.
3228 Diag(Tok, diag::err_requires_expr_missing_arrow)
3229 << FixItHint::CreateInsertion(Tok.getLocation(), "->");
3230 // Try to parse a 'type-constraint'
3231 if (TryAnnotateTypeConstraint()) {
3232 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3233 break;
3234 }
3235 if (!isTypeConstraintAnnotation()) {
3236 Diag(Tok, diag::err_requires_expr_expected_type_constraint);
3237 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3238 break;
3239 }
3240 CXXScopeSpec SS;
3241 if (Tok.is(K: tok::annot_cxxscope)) {
3242 Actions.RestoreNestedNameSpecifierAnnotation(Annotation: Tok.getAnnotationValue(),
3243 AnnotationRange: Tok.getAnnotationRange(),
3244 SS);
3245 ConsumeAnnotationToken();
3246 }
3247
3248 Req = Actions.ActOnCompoundRequirement(
3249 E: Expression.get(), NoexceptLoc, SS, TypeConstraint: takeTemplateIdAnnotation(tok: Tok),
3250 Depth: TemplateParameterDepth);
3251 ConsumeAnnotationToken();
3252 if (Req)
3253 Requirements.push_back(Elt: Req);
3254 break;
3255 }
3256 default: {
3257 bool PossibleRequiresExprInSimpleRequirement = false;
3258 if (Tok.is(K: tok::kw_requires)) {
3259 auto IsNestedRequirement = [&] {
3260 RevertingTentativeParsingAction TPA(*this);
3261 ConsumeToken(); // 'requires'
3262 if (Tok.is(K: tok::l_brace))
3263 // This is a requires expression
3264 // requires (T t) {
3265 // requires { t++; };
3266 // ... ^
3267 // }
3268 return false;
3269 if (Tok.is(K: tok::l_paren)) {
3270 // This might be the parameter list of a requires expression
3271 ConsumeParen();
3272 auto Res = TryParseParameterDeclarationClause();
3273 if (Res != TPResult::False) {
3274 // Skip to the closing parenthesis
3275 unsigned Depth = 1;
3276 while (Depth != 0) {
3277 bool FoundParen = SkipUntil(T1: tok::l_paren, T2: tok::r_paren,
3278 Flags: SkipUntilFlags::StopBeforeMatch);
3279 if (!FoundParen)
3280 break;
3281 if (Tok.is(K: tok::l_paren))
3282 Depth++;
3283 else if (Tok.is(K: tok::r_paren))
3284 Depth--;
3285 ConsumeAnyToken();
3286 }
3287 // requires (T t) {
3288 // requires () ?
3289 // ... ^
3290 // - OR -
3291 // requires (int x) ?
3292 // ... ^
3293 // }
3294 if (Tok.is(K: tok::l_brace))
3295 // requires (...) {
3296 // ^ - a requires expression as a
3297 // simple-requirement.
3298 return false;
3299 }
3300 }
3301 return true;
3302 };
3303 if (IsNestedRequirement()) {
3304 ConsumeToken();
3305 // Nested requirement
3306 // C++ [expr.prim.req.nested]
3307 // nested-requirement:
3308 // 'requires' constraint-expression ';'
3309 ExprResult ConstraintExpr =
3310 Actions.CorrectDelayedTyposInExpr(ER: ParseConstraintExpression());
3311 if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) {
3312 SkipUntil(T1: tok::semi, T2: tok::r_brace,
3313 Flags: SkipUntilFlags::StopBeforeMatch);
3314 break;
3315 }
3316 if (auto *Req =
3317 Actions.ActOnNestedRequirement(Constraint: ConstraintExpr.get()))
3318 Requirements.push_back(Elt: Req);
3319 else {
3320 SkipUntil(T1: tok::semi, T2: tok::r_brace,
3321 Flags: SkipUntilFlags::StopBeforeMatch);
3322 break;
3323 }
3324 break;
3325 } else
3326 PossibleRequiresExprInSimpleRequirement = true;
3327 } else if (Tok.is(K: tok::kw_typename)) {
3328 // This might be 'typename T::value_type;' (a type requirement) or
3329 // 'typename T::value_type{};' (a simple requirement).
3330 TentativeParsingAction TPA(*this);
3331
3332 // We need to consume the typename to allow 'requires { typename a; }'
3333 SourceLocation TypenameKWLoc = ConsumeToken();
3334 if (TryAnnotateOptionalCXXScopeToken()) {
3335 TPA.Commit();
3336 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3337 break;
3338 }
3339 CXXScopeSpec SS;
3340 if (Tok.is(K: tok::annot_cxxscope)) {
3341 Actions.RestoreNestedNameSpecifierAnnotation(
3342 Annotation: Tok.getAnnotationValue(), AnnotationRange: Tok.getAnnotationRange(), SS);
3343 ConsumeAnnotationToken();
3344 }
3345
3346 if (Tok.isOneOf(K1: tok::identifier, K2: tok::annot_template_id) &&
3347 !NextToken().isOneOf(K1: tok::l_brace, K2: tok::l_paren)) {
3348 TPA.Commit();
3349 SourceLocation NameLoc = Tok.getLocation();
3350 IdentifierInfo *II = nullptr;
3351 TemplateIdAnnotation *TemplateId = nullptr;
3352 if (Tok.is(K: tok::identifier)) {
3353 II = Tok.getIdentifierInfo();
3354 ConsumeToken();
3355 } else {
3356 TemplateId = takeTemplateIdAnnotation(tok: Tok);
3357 ConsumeAnnotationToken();
3358 if (TemplateId->isInvalid())
3359 break;
3360 }
3361
3362 if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS,
3363 NameLoc, TypeName: II,
3364 TemplateId)) {
3365 Requirements.push_back(Elt: Req);
3366 }
3367 break;
3368 }
3369 TPA.Revert();
3370 }
3371 // Simple requirement
3372 // C++ [expr.prim.req.simple]
3373 // simple-requirement:
3374 // expression ';'
3375 SourceLocation StartLoc = Tok.getLocation();
3376 ExprResult Expression =
3377 Actions.CorrectDelayedTyposInExpr(ER: ParseExpression());
3378 if (!Expression.isUsable()) {
3379 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3380 break;
3381 }
3382 if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)
3383 Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)
3384 << FixItHint::CreateInsertion(StartLoc, "requires");
3385 if (auto *Req = Actions.ActOnSimpleRequirement(E: Expression.get()))
3386 Requirements.push_back(Elt: Req);
3387 else {
3388 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3389 break;
3390 }
3391 // User may have tried to put some compound requirement stuff here
3392 if (Tok.is(K: tok::kw_noexcept)) {
3393 Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept)
3394 << FixItHint::CreateInsertion(StartLoc, "{")
3395 << FixItHint::CreateInsertion(Tok.getLocation(), "}");
3396 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3397 break;
3398 }
3399 break;
3400 }
3401 }
3402 if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) {
3403 SkipUntil(T1: tok::semi, T2: tok::r_brace, Flags: SkipUntilFlags::StopBeforeMatch);
3404 TryConsumeToken(Expected: tok::semi);
3405 break;
3406 }
3407 }
3408 if (Requirements.empty()) {
3409 // Don't emit an empty requires expr here to avoid confusing the user with
3410 // other diagnostics quoting an empty requires expression they never
3411 // wrote.
3412 Braces.consumeClose();
3413 Actions.ActOnFinishRequiresExpr();
3414 return ExprError();
3415 }
3416 }
3417 Braces.consumeClose();
3418 Actions.ActOnFinishRequiresExpr();
3419 ParsingBodyDecl.complete(Body);
3420 return Actions.ActOnRequiresExpr(
3421 RequiresKWLoc, Body, LParenLoc: Parens.getOpenLocation(), LocalParameters: LocalParameterDecls,
3422 RParenLoc: Parens.getCloseLocation(), Requirements, ClosingBraceLoc: Braces.getCloseLocation());
3423}
3424
3425static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
3426 switch (kind) {
3427 default: llvm_unreachable("Not a known type trait");
3428#define TYPE_TRAIT_1(Spelling, Name, Key) \
3429case tok::kw_ ## Spelling: return UTT_ ## Name;
3430#define TYPE_TRAIT_2(Spelling, Name, Key) \
3431case tok::kw_ ## Spelling: return BTT_ ## Name;
3432#include "clang/Basic/TokenKinds.def"
3433#define TYPE_TRAIT_N(Spelling, Name, Key) \
3434 case tok::kw_ ## Spelling: return TT_ ## Name;
3435#include "clang/Basic/TokenKinds.def"
3436 }
3437}
3438
3439static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
3440 switch (kind) {
3441 default:
3442 llvm_unreachable("Not a known array type trait");
3443#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \
3444 case tok::kw_##Spelling: \
3445 return ATT_##Name;
3446#include "clang/Basic/TokenKinds.def"
3447 }
3448}
3449
3450static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
3451 switch (kind) {
3452 default:
3453 llvm_unreachable("Not a known unary expression trait.");
3454#define EXPRESSION_TRAIT(Spelling, Name, Key) \
3455 case tok::kw_##Spelling: \
3456 return ET_##Name;
3457#include "clang/Basic/TokenKinds.def"
3458 }
3459}
3460
3461ExprResult Parser::ParseTypeTrait() {
3462 tok::TokenKind Kind = Tok.getKind();
3463
3464 SourceLocation Loc = ConsumeToken();
3465
3466 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3467 if (Parens.expectAndConsume())
3468 return ExprError();
3469
3470 SmallVector<ParsedType, 2> Args;
3471 do {
3472 // Parse the next type.
3473 TypeResult Ty = ParseTypeName(/*SourceRange=*/Range: nullptr,
3474 Context: getLangOpts().CPlusPlus
3475 ? DeclaratorContext::TemplateTypeArg
3476 : DeclaratorContext::TypeName);
3477 if (Ty.isInvalid()) {
3478 Parens.skipToEnd();
3479 return ExprError();
3480 }
3481
3482 // Parse the ellipsis, if present.
3483 if (Tok.is(K: tok::ellipsis)) {
3484 Ty = Actions.ActOnPackExpansion(Type: Ty.get(), EllipsisLoc: ConsumeToken());
3485 if (Ty.isInvalid()) {
3486 Parens.skipToEnd();
3487 return ExprError();
3488 }
3489 }
3490
3491 // Add this type to the list of arguments.
3492 Args.push_back(Elt: Ty.get());
3493 } while (TryConsumeToken(Expected: tok::comma));
3494
3495 if (Parens.consumeClose())
3496 return ExprError();
3497
3498 SourceLocation EndLoc = Parens.getCloseLocation();
3499
3500 return Actions.ActOnTypeTrait(Kind: TypeTraitFromTokKind(kind: Kind), KWLoc: Loc, Args, RParenLoc: EndLoc);
3501}
3502
3503ExprResult Parser::ParseArrayTypeTrait() {
3504 ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(kind: Tok.getKind());
3505 SourceLocation Loc = ConsumeToken();
3506
3507 BalancedDelimiterTracker T(*this, tok::l_paren);
3508 if (T.expectAndConsume())
3509 return ExprError();
3510
3511 TypeResult Ty = ParseTypeName(/*SourceRange=*/Range: nullptr,
3512 Context: DeclaratorContext::TemplateTypeArg);
3513 if (Ty.isInvalid()) {
3514 SkipUntil(T: tok::comma, Flags: StopAtSemi);
3515 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
3516 return ExprError();
3517 }
3518
3519 switch (ATT) {
3520 case ATT_ArrayRank: {
3521 T.consumeClose();
3522 return Actions.ActOnArrayTypeTrait(ATT, KWLoc: Loc, LhsTy: Ty.get(), DimExpr: nullptr,
3523 RParen: T.getCloseLocation());
3524 }
3525 case ATT_ArrayExtent: {
3526 if (ExpectAndConsume(ExpectedTok: tok::comma)) {
3527 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
3528 return ExprError();
3529 }
3530
3531 ExprResult DimExpr = ParseExpression();
3532 T.consumeClose();
3533
3534 if (DimExpr.isInvalid())
3535 return ExprError();
3536
3537 return Actions.ActOnArrayTypeTrait(ATT, KWLoc: Loc, LhsTy: Ty.get(), DimExpr: DimExpr.get(),
3538 RParen: T.getCloseLocation());
3539 }
3540 }
3541 llvm_unreachable("Invalid ArrayTypeTrait!");
3542}
3543
3544ExprResult Parser::ParseExpressionTrait() {
3545 ExpressionTrait ET = ExpressionTraitFromTokKind(kind: Tok.getKind());
3546 SourceLocation Loc = ConsumeToken();
3547
3548 BalancedDelimiterTracker T(*this, tok::l_paren);
3549 if (T.expectAndConsume())
3550 return ExprError();
3551
3552 ExprResult Expr = ParseExpression();
3553
3554 T.consumeClose();
3555
3556 return Actions.ActOnExpressionTrait(OET: ET, KWLoc: Loc, Queried: Expr.get(),
3557 RParen: T.getCloseLocation());
3558}
3559
3560ExprResult
3561Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
3562 ParsedType &CastTy,
3563 BalancedDelimiterTracker &Tracker,
3564 ColonProtectionRAIIObject &ColonProt) {
3565 assert(getLangOpts().CPlusPlus && "Should only be called for C++!");
3566 assert(ExprType == ParenParseOption::CastExpr &&
3567 "Compound literals are not ambiguous!");
3568 assert(isTypeIdInParens() && "Not a type-id!");
3569
3570 ExprResult Result(true);
3571 CastTy = nullptr;
3572
3573 // We need to disambiguate a very ugly part of the C++ syntax:
3574 //
3575 // (T())x; - type-id
3576 // (T())*x; - type-id
3577 // (T())/x; - expression
3578 // (T()); - expression
3579 //
3580 // The bad news is that we cannot use the specialized tentative parser, since
3581 // it can only verify that the thing inside the parens can be parsed as
3582 // type-id, it is not useful for determining the context past the parens.
3583 //
3584 // The good news is that the parser can disambiguate this part without
3585 // making any unnecessary Action calls.
3586 //
3587 // It uses a scheme similar to parsing inline methods. The parenthesized
3588 // tokens are cached, the context that follows is determined (possibly by
3589 // parsing a cast-expression), and then we re-introduce the cached tokens
3590 // into the token stream and parse them appropriately.
3591
3592 ParenParseOption ParseAs;
3593 CachedTokens Toks;
3594
3595 // Store the tokens of the parentheses. We will parse them after we determine
3596 // the context that follows them.
3597 if (!ConsumeAndStoreUntil(T1: tok::r_paren, Toks)) {
3598 // We didn't find the ')' we expected.
3599 Tracker.consumeClose();
3600 return ExprError();
3601 }
3602
3603 if (Tok.is(K: tok::l_brace)) {
3604 ParseAs = ParenParseOption::CompoundLiteral;
3605 } else {
3606 bool NotCastExpr;
3607 if (Tok.is(K: tok::l_paren) && NextToken().is(K: tok::r_paren)) {
3608 NotCastExpr = true;
3609 } else {
3610 // Try parsing the cast-expression that may follow.
3611 // If it is not a cast-expression, NotCastExpr will be true and no token
3612 // will be consumed.
3613 ColonProt.restore();
3614 Result = ParseCastExpression(ParseKind: CastParseKind::AnyCastExpr,
3615 isAddressOfOperand: false /*isAddressofOperand*/, NotCastExpr,
3616 // type-id has priority.
3617 isTypeCast: TypeCastState::IsTypeCast);
3618 }
3619
3620 // If we parsed a cast-expression, it's really a type-id, otherwise it's
3621 // an expression.
3622 ParseAs =
3623 NotCastExpr ? ParenParseOption::SimpleExpr : ParenParseOption::CastExpr;
3624 }
3625
3626 // Create a fake EOF to mark end of Toks buffer.
3627 Token AttrEnd;
3628 AttrEnd.startToken();
3629 AttrEnd.setKind(tok::eof);
3630 AttrEnd.setLocation(Tok.getLocation());
3631 AttrEnd.setEofData(Toks.data());
3632 Toks.push_back(Elt: AttrEnd);
3633
3634 // The current token should go after the cached tokens.
3635 Toks.push_back(Elt: Tok);
3636 // Re-enter the stored parenthesized tokens into the token stream, so we may
3637 // parse them now.
3638 PP.EnterTokenStream(Toks, /*DisableMacroExpansion*/ true,
3639 /*IsReinject*/ true);
3640 // Drop the current token and bring the first cached one. It's the same token
3641 // as when we entered this function.
3642 ConsumeAnyToken();
3643
3644 if (ParseAs >= ParenParseOption::CompoundLiteral) {
3645 // Parse the type declarator.
3646 DeclSpec DS(AttrFactory);
3647 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3648 DeclaratorContext::TypeName);
3649 {
3650 ColonProtectionRAIIObject InnerColonProtection(*this);
3651 ParseSpecifierQualifierList(DS);
3652 ParseDeclarator(D&: DeclaratorInfo);
3653 }
3654
3655 // Match the ')'.
3656 Tracker.consumeClose();
3657 ColonProt.restore();
3658
3659 // Consume EOF marker for Toks buffer.
3660 assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());
3661 ConsumeAnyToken();
3662
3663 if (ParseAs == ParenParseOption::CompoundLiteral) {
3664 ExprType = ParenParseOption::CompoundLiteral;
3665 if (DeclaratorInfo.isInvalidType())
3666 return ExprError();
3667
3668 TypeResult Ty = Actions.ActOnTypeName(D&: DeclaratorInfo);
3669 return ParseCompoundLiteralExpression(Ty: Ty.get(),
3670 LParenLoc: Tracker.getOpenLocation(),
3671 RParenLoc: Tracker.getCloseLocation());
3672 }
3673
3674 // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
3675 assert(ParseAs == ParenParseOption::CastExpr);
3676
3677 if (DeclaratorInfo.isInvalidType())
3678 return ExprError();
3679
3680 // Result is what ParseCastExpression returned earlier.
3681 if (!Result.isInvalid())
3682 Result = Actions.ActOnCastExpr(S: getCurScope(), LParenLoc: Tracker.getOpenLocation(),
3683 D&: DeclaratorInfo, Ty&: CastTy,
3684 RParenLoc: Tracker.getCloseLocation(), CastExpr: Result.get());
3685 return Result;
3686 }
3687
3688 // Not a compound literal, and not followed by a cast-expression.
3689 assert(ParseAs == ParenParseOption::SimpleExpr);
3690
3691 ExprType = ParenParseOption::SimpleExpr;
3692 Result = ParseExpression();
3693 if (!Result.isInvalid() && Tok.is(K: tok::r_paren))
3694 Result = Actions.ActOnParenExpr(L: Tracker.getOpenLocation(),
3695 R: Tok.getLocation(), E: Result.get());
3696
3697 // Match the ')'.
3698 if (Result.isInvalid()) {
3699 while (Tok.isNot(K: tok::eof))
3700 ConsumeAnyToken();
3701 assert(Tok.getEofData() == AttrEnd.getEofData());
3702 ConsumeAnyToken();
3703 return ExprError();
3704 }
3705
3706 Tracker.consumeClose();
3707 // Consume EOF marker for Toks buffer.
3708 assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());
3709 ConsumeAnyToken();
3710 return Result;
3711}
3712
3713ExprResult Parser::ParseBuiltinBitCast() {
3714 SourceLocation KWLoc = ConsumeToken();
3715
3716 BalancedDelimiterTracker T(*this, tok::l_paren);
3717 if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast"))
3718 return ExprError();
3719
3720 // Parse the common declaration-specifiers piece.
3721 DeclSpec DS(AttrFactory);
3722 ParseSpecifierQualifierList(DS);
3723
3724 // Parse the abstract-declarator, if present.
3725 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3726 DeclaratorContext::TypeName);
3727 ParseDeclarator(D&: DeclaratorInfo);
3728
3729 if (ExpectAndConsume(ExpectedTok: tok::comma)) {
3730 Diag(Tok.getLocation(), diag::err_expected) << tok::comma;
3731 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
3732 return ExprError();
3733 }
3734
3735 ExprResult Operand = ParseExpression();
3736
3737 if (T.consumeClose())
3738 return ExprError();
3739
3740 if (Operand.isInvalid() || DeclaratorInfo.isInvalidType())
3741 return ExprError();
3742
3743 return Actions.ActOnBuiltinBitCastExpr(KWLoc, Dcl&: DeclaratorInfo, Operand,
3744 RParenLoc: T.getCloseLocation());
3745}
3746

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Parse/ParseExprCXX.cpp