clang: lib/Parse/ParseExprCXX.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

28#include "llvm/Support/Compiler.h"

29#include "llvm/Support/ErrorHandling.h"

30#include

31

32using namespace clang;

33

35 switch (Kind) {

36

37 case tok::unknown: return 0;

38

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

49

50bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {

54 return FirstEnd == SM.getSpellingLoc(Second.getLocation());

55}

56

57

60

61 if (!AtDigraph)

62 PP.Lex(DigraphToken);

63 PP.Lex(ColonToken);

64

68 P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)

71

72

73 ColonToken.setKind(tok::coloncolon);

76 DigraphToken.setKind(tok::less);

78

79

80 PP.EnterToken(ColonToken, true);

81 if (!AtDigraph)

82 PP.EnterToken(DigraphToken, true);

83}

84

85

86

87void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,

88 bool EnteringContext,

90 if (!Next.is(tok::l_square) || Next.getLength() != 2)

91 return;

92

93 Token SecondToken = GetLookAheadToken(2);

94 if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken))

95 return;

96

100 bool MemberOfUnknownSpecialization;

103 Template, MemberOfUnknownSpecialization))

104 return;

105

106 FixDigraph(*this, PP, Next, SecondToken, tok::unknown,

107 false);

108}

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159bool Parser::ParseOptionalCXXScopeSpecifier(

161 bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename,

162 const IdentifierInfo **LastII, bool OnlyNamespace, bool InUsingDeclaration,

163 bool Disambiguation) {

165 "Call sites of this function should be guarded by checking for C++");

166

167 if (Tok.is(tok::annot_cxxscope)) {

168 assert(!LastII && "want last identifier but have already annotated scope");

169 assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");

172 SS);

173 ConsumeAnnotationToken();

174 return false;

175 }

176

177

178 bool CheckForDestructor = false;

179 if (MayBePseudoDestructor && *MayBePseudoDestructor) {

180 CheckForDestructor = true;

181 *MayBePseudoDestructor = false;

182 }

183

184 if (LastII)

185 *LastII = nullptr;

186

187 bool HasScopeSpecifier = false;

188

189 if (Tok.is(tok::coloncolon)) {

190

192 if (NextKind == tok::kw_new || NextKind == tok::kw_delete)

193 return false;

194

195 if (NextKind == tok::l_brace) {

196

197

199 } else {

200

202 return true;

203

204 HasScopeSpecifier = true;

205 }

206 }

207

208 if (Tok.is(tok::kw___super)) {

210 if (!Tok.is(tok::coloncolon)) {

211 Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);

212 return true;

213 }

214

216 }

217

218 if (!HasScopeSpecifier &&

219 Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {

223

225

226

229 AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);

230 return false;

231 }

232

235

236 HasScopeSpecifier = true;

237 }

238

239 else if (!HasScopeSpecifier && Tok.is(tok::identifier) &&

240 GetLookAheadToken(1).is(tok::ellipsis) &&

241 GetLookAheadToken(2).is(tok::l_square) &&

242 !GetLookAheadToken(3).is(tok::r_square)) {

248 return false;

249

251 DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(),

252 DS.getEllipsisLoc());

253

254 if (Type.isNull())

255 return false;

256

257

258

259

260

261

262

263

264

265

267 getCurScope()->isFunctionDeclarationScope())

268 Diag(Start, diag::warn_pre_cxx26_ambiguous_pack_indexing_type) << Type;

269

272 EndLoc);

273 return false;

274 }

276 std::move(Type)))

278 HasScopeSpecifier = true;

279 }

280

281

282 auto SavedType = PreferredType;

283 while (true) {

284 if (HasScopeSpecifier) {

285 if (Tok.is(tok::code_completion)) {

286 cutOffParsing();

287

288

290 getCurScope(), SS, EnteringContext, InUsingDeclaration,

292

293

294

295

297 return true;

298 }

299

300

301

302

303

304

305

306

307

308

309

310 ObjectType = nullptr;

311 }

312

313

314

315

316

317

318 if (Tok.is(tok::kw_template)) {

319

320

321

322 if (!HasScopeSpecifier && !ObjectType)

323 break;

324

325 TentativeParsingAction TPA(*this);

327

329 if (Tok.is(tok::identifier)) {

330

333 } else if (Tok.is(tok::kw_operator)) {

334

335

336

337

338 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,

340 TPA.Commit();

341 break;

342 }

343

347 diag::err_id_after_template_in_nested_name_spec)

349 TPA.Commit();

350 break;

351 }

352 } else {

353 TPA.Revert();

354 break;

355 }

356

357

358

359

360 if (Tok.isNot(tok::less)) {

361 TPA.Revert();

362 break;

363 }

364

365

366 TPA.Commit();

370 EnteringContext, Template, true);

371 if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,

373 return true;

374

375 continue;

376 }

377

378 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {

379

380

381

382

383

384

385

387 if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {

388 *MayBePseudoDestructor = true;

389 return false;

390 }

391

392 if (LastII)

393 *LastII = TemplateId->Name;

394

395

396 ConsumeAnnotationToken();

397

398 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");

400

401 HasScopeSpecifier = true;

402

405

408 SS,

413 TemplateArgsPtr,

415 CCLoc,

416 EnteringContext)) {

421 }

422

423 continue;

424 }

425

427#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:

428#include "clang/Basic/TransformTypeTraits.def"

429 if (NextToken().is(tok::l_paren)) {

430 Tok.setKind(tok::identifier);

431 Diag(Tok, diag::ext_keyword_as_ident)

433 continue;

434 }

435 [[fallthrough]];

436 default:

437 break;

438 }

439

440

441

442 if (Tok.isNot(tok::identifier))

443 break;

444

446

447

448

449

450

453 ObjectType);

454

455

456

457 if (Next.is(tok::colon) && !ColonIsSacred) {

459 EnteringContext) &&

460

461

462

464 Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)

466

467 Next.setKind(tok::coloncolon);

468 }

469 }

470

471 if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) {

472

473

475 ConsumeToken();

477 << tok::identifier;

478 UnconsumeToken(Identifier);

479 Next = NextToken();

480 }

481

482 if (Next.is(tok::coloncolon)) {

483 if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {

484 *MayBePseudoDestructor = true;

485 return false;

486 }

487

488 if (ColonIsSacred) {

489 const Token &Next2 = GetLookAheadToken(2);

490 if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||

491 Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {

492 Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)

495 Token ColonColon;

496 PP.Lex(ColonColon);

497 ColonColon.setKind(tok::colon);

498 PP.EnterToken(ColonColon, true);

499 break;

500 }

501 }

502

503 if (LastII)

504 *LastII = &II;

505

506

507

510 assert(Tok.isOneOf(tok::coloncolon, tok::colon) &&

511 "NextToken() not working properly!");

512 Token ColonColon = Tok;

514

515 bool IsCorrectedToColon = false;

516 bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;

518 getCurScope(), IdInfo, EnteringContext, SS, CorrectionFlagPtr,

519 OnlyNamespace)) {

520

521

522 if (CorrectionFlagPtr && IsCorrectedToColon) {

523 ColonColon.setKind(tok::colon);

524 PP.EnterToken(Tok, true);

525 PP.EnterToken(ColonColon, true);

527 break;

528 }

530 }

531 HasScopeSpecifier = true;

532 continue;

533 }

534

535 CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);

536

537

538

539 if (Next.is(tok::less)) {

540

544 bool MemberOfUnknownSpecialization;

547 false, TemplateName, ObjectType,

548 EnteringContext, Template, MemberOfUnknownSpecialization,

549 Disambiguation)) {

550

551

552

553

555 isTemplateArgumentList(1) == TPResult::False)

556 break;

557

558

559

560

561

562

563

564

566 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),

568 return true;

569 continue;

570 }

571

572 if (MemberOfUnknownSpecialization && !Disambiguation &&

573 (ObjectType || SS.isSet()) &&

574 (IsTypename || isTemplateArgumentList(1) == TPResult::True)) {

575

576

577 if (!ObjectHadErrors) {

578

579

580

581

582 unsigned DiagID = diag::err_missing_dependent_template_keyword;

584 DiagID = diag::warn_missing_dependent_template_keyword;

585

589 }

590

592

595 EnteringContext, Template, true);

596 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),

598 return true;

599

600 continue;

601 }

602 }

603

604

605

606 break;

607 }

608

609

610

611

612 if (CheckForDestructor && !HasScopeSpecifier && Tok.is(tok::tilde))

613 *MayBePseudoDestructor = true;

614

615 return false;

616}

617

619 bool isAddressOfOperand,

620 Token &Replacement) {

622

623

625 case tok::annot_non_type: {

626 NamedDecl *ND = getNonTypeAnnotation(Tok);

629 break;

630 }

631

632 case tok::annot_non_type_dependent: {

635

636

637

638 if (isAddressOfOperand && isPostfixExpressionSuffixStart())

639 isAddressOfOperand = false;

640

642 isAddressOfOperand);

643 break;

644 }

645

646 case tok::annot_non_type_undeclared: {

648 "undeclared non-type annotation should be unqualified");

652 break;

653 }

654

655 default:

659 false,

660 false,

661 false,

662 false,

663 false, &TemplateKWLoc, Name))

665

666

667

668 if (isAddressOfOperand && isPostfixExpressionSuffixStart())

669 isAddressOfOperand = false;

670

672 getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren),

673 isAddressOfOperand, nullptr, false,

674 &Replacement);

675 break;

676 }

677

678

679 E = tryParseCXXPackIndexingExpression(E);

680

681 if (E.isInvalid() && E.isUnset() && Tok.is(tok::less))

682 checkPotentialAngleBracket(E);

683 return E;

684}

685

686ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) {

687 assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) &&

688 "expected ...[");

691 T.consumeOpen();

693 if (T.consumeClose() || IndexExpr.isInvalid())

696 EllipsisLoc, T.getOpenLocation(),

697 IndexExpr.get(), T.getCloseLocation());

698}

699

701Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) {

703 if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() &&

704 Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) {

705 E = ParseCXXPackIndexingExpression(E);

706 }

707 return E;

708}

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

748

749

750

751

752ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {

753

754

755

756

758 ParseOptionalCXXScopeSpecifier(SS, nullptr,

759 false,

760 false);

761

762 Token Replacement;

764 tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);

765 if (Result.isUnset()) {

766

767

768 UnconsumeToken(Replacement);

769 Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);

770 }

771 assert(Result.isUnset() && "Typo correction suggested a keyword replacement "

772 "for a previous keyword suggestion");

774}

775

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

812

813

814

815

816

817

818

819

820

821ExprResult Parser::ParseLambdaExpression() {

822

824 if (ParseLambdaIntroducer(Intro)) {

829 }

830

831 return ParseLambdaExpressionAfterIntroducer(Intro);

832}

833

834

835

836

837

838ExprResult Parser::TryParseLambdaExpression() {

840 "Not at the start of a possible lambda expression.");

841

843 if (Next.is(tok::eof))

845

846 const Token After = GetLookAheadToken(2);

847

848 if (Next.is(tok::r_square) ||

849 Next.is(tok::equal) ||

850 (Next.is(tok::amp) &&

851 After.isOneOf(tok::r_square, tok::comma)) ||

852 (Next.is(tok::identifier) &&

853 After.is(tok::r_square)) ||

854 Next.is(tok::ellipsis)) {

855 return ParseLambdaExpression();

856 }

857

858

859

860 if (Next.is(tok::identifier) && After.is(tok::identifier))

862

863

864

865

866

867

869 {

870 TentativeParsingAction TPA(*this);

871 LambdaIntroducerTentativeParse Tentative;

872 if (ParseLambdaIntroducer(Intro, &Tentative)) {

873 TPA.Commit();

875 }

876

877 switch (Tentative) {

878 case LambdaIntroducerTentativeParse::Success:

879 TPA.Commit();

880 break;

881

882 case LambdaIntroducerTentativeParse::Incomplete:

883

884

885 TPA.Revert();

887 if (ParseLambdaIntroducer(Intro))

889 break;

890

891 case LambdaIntroducerTentativeParse::MessageSend:

892 case LambdaIntroducerTentativeParse::Invalid:

893

894 TPA.Revert();

896 }

897 }

898

899 return ParseLambdaExpressionAfterIntroducer(Intro);

900}

901

902

903

904

905

906

907

908

909

910

912 LambdaIntroducerTentativeParse *Tentative) {

913 if (Tentative)

914 *Tentative = LambdaIntroducerTentativeParse::Success;

915

916 assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");

918 T.consumeOpen();

919

921

922 bool First = true;

923

924

925

926 auto Invalid = [&](llvm::function_ref<void()> Action) {

927 if (Tentative) {

928 *Tentative = LambdaIntroducerTentativeParse::Invalid;

929 return false;

930 }

931 Action();

932 return true;

933 };

934

935

936

937 auto NonTentativeAction = [&](llvm::function_ref<void()> Action) {

938 if (Tentative)

939 *Tentative = LambdaIntroducerTentativeParse::Incomplete;

940 else

941 Action();

942 };

943

944

945 if (Tok.is(tok::amp) &&

951

952

953 Tentative = nullptr;

954 }

955 } else if (Tok.is(tok::equal)) {

959 Tentative = nullptr;

960 }

961

962 while (Tok.isNot(tok::r_square)) {

964 if (Tok.isNot(tok::comma)) {

965

966

967

968

969 if (Tok.is(tok::code_completion) &&

971 cutOffParsing();

974 false);

975 break;

976 }

977

979 Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);

980 });

981 }

983 }

984

985 if (Tok.is(tok::code_completion)) {

986 cutOffParsing();

987

988

991 else

994 false);

995 break;

996 }

997

999

1000

1008

1009 if (Tok.is(tok::star)) {

1011 if (Tok.is(tok::kw_this)) {

1014 } else {

1016 Diag(Tok.getLocation(), diag::err_expected_star_this_capture);

1017 });

1018 }

1019 } else if (Tok.is(tok::kw_this)) {

1022 } else if (Tok.isOneOf(tok::amp, tok::equal) &&

1025

1026

1027

1028

1030 [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });

1031 } else {

1033

1034 if (Tok.is(tok::amp)) {

1037

1038 if (Tok.is(tok::code_completion)) {

1039 cutOffParsing();

1042 true);

1043 break;

1044 }

1045 }

1046

1048

1049 if (Tok.is(tok::identifier)) {

1052 } else if (Tok.is(tok::kw_this)) {

1054

1055 Diag(Tok.getLocation(), diag::err_this_captured_by_reference);

1056 });

1057 } else {

1060 });

1061 }

1062

1064

1065 if (Tok.is(tok::l_paren)) {

1067 Parens.consumeOpen();

1068

1070

1071 ExprVector Exprs;

1072 if (Tentative) {

1074 *Tentative = LambdaIntroducerTentativeParse::Incomplete;

1075 } else if (ParseExpressionList(Exprs)) {

1078 } else {

1079 Parens.consumeClose();

1081 Parens.getCloseLocation(),

1082 Exprs);

1083 }

1084 } else if (Tok.isOneOf(tok::l_brace, tok::equal)) {

1085

1086

1087

1090

1093 else

1095

1096 if (!Tentative) {

1097 Init = ParseInitializer();

1098 } else if (Tok.is(tok::l_brace)) {

1100 Braces.consumeOpen();

1102 *Tentative = LambdaIntroducerTentativeParse::Incomplete;

1103 } else {

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

1121

1122

1123

1126 Init = ParseInitializer();

1127 if (Init.isInvalid())

1129

1131

1133

1134

1136 Tok.setKind(tok::annot_primary_expr);

1137 setExprAnnotation(Tok, Init);

1140

1141

1142 ConsumeAnnotationToken();

1143 }

1144 }

1145 }

1146

1148 }

1149

1150

1151 if (Tentative && Tok.is(tok::identifier) &&

1153

1154 *Tentative = LambdaIntroducerTentativeParse::MessageSend;

1155 return false;

1156 }

1157

1158

1160 if (llvm::any_of(EllipsisLocs,

1162

1163

1166 !InitCapture ? &EllipsisLocs[2] :

1168 &EllipsisLocs[0];

1169 EllipsisLoc = *ExpectedEllipsisLoc;

1170

1171 unsigned DiagID = 0;

1173 DiagID = diag::err_lambda_capture_misplaced_ellipsis;

1176 EllipsisLoc = Loc;

1177 }

1178 } else {

1179 unsigned NumEllipses = std::accumulate(

1180 std::begin(EllipsisLocs), std::end(EllipsisLocs), 0,

1182 if (NumEllipses > 1)

1183 DiagID = diag::err_lambda_capture_multiple_ellipses;

1184 }

1185 if (DiagID) {

1186 NonTentativeAction([&] {

1187

1190 if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) {

1191 DiagLoc = Loc;

1192 break;

1193 }

1194 }

1195 assert(DiagLoc.isValid() && "no location for diagnostic");

1196

1197

1198

1199 auto &&D = Diag(DiagLoc, DiagID);

1200 if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) {

1202 InitCapture ? Loc

1206 }

1208 if (&Loc != ExpectedEllipsisLoc && Loc.isValid())

1210 }

1211 });

1212 }

1213 }

1214

1215

1216

1217

1218

1220 if (Init.isUsable())

1222 if (Init.isUsable()) {

1223 NonTentativeAction([&] {

1224

1225

1226 Expr *InitExpr = Init.get();

1227

1228

1230 Loc, Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, InitExpr);

1231 Init = InitExpr;

1232 });

1233 }

1234

1236

1238 InitCaptureType, SourceRange(LocStart, LocEnd));

1239 }

1240

1241 T.consumeClose();

1243 return false;

1244}

1245

1254 assert(ConstexprLoc.isInvalid());

1255 assert(ConstevalLoc.isInvalid());

1256

1257

1258

1259

1260 auto ConsumeLocation = [&P, &DeclEndLoc](SourceLocation &SpecifierLoc,

1261 int DiagIndex) {

1262 if (SpecifierLoc.isValid()) {

1263 P.Diag(P.getCurToken().getLocation(),

1264 diag::err_lambda_decl_specifier_repeated)

1265 << DiagIndex

1267 }

1268 SpecifierLoc = P.ConsumeToken();

1269 DeclEndLoc = SpecifierLoc;

1270 };

1271

1272 while (true) {

1273 switch (P.getCurToken().getKind()) {

1274 case tok::kw_mutable:

1275 ConsumeLocation(MutableLoc, 0);

1276 break;

1277 case tok::kw_static:

1278 ConsumeLocation(StaticLoc, 1);

1279 break;

1280 case tok::kw_constexpr:

1281 ConsumeLocation(ConstexprLoc, 2);

1282 break;

1283 case tok::kw_consteval:

1284 ConsumeLocation(ConstevalLoc, 3);

1285 break;

1286 default:

1287 return;

1288 }

1289 }

1290}

1291

1294 if (StaticLoc.isValid()) {

1295 P.Diag(StaticLoc, P.getLangOpts().CPlusPlus23

1296 ? diag::err_static_lambda

1297 : diag::warn_cxx20_compat_static_lambda);

1298 const char *PrevSpec = nullptr;

1299 unsigned DiagID = 0;

1301 PrevSpec, DiagID,

1302 P.getActions().getASTContext().getPrintingPolicy());

1303 assert(PrevSpec == nullptr && DiagID == 0 &&

1304 "Static cannot have been set previously!");

1305 }

1306}

1307

1308static void

1311 if (ConstexprLoc.isValid()) {

1312 P.Diag(ConstexprLoc, P.getLangOpts().CPlusPlus17

1313 ? diag::ext_constexpr_on_lambda_cxx17

1314 : diag::warn_cxx14_compat_constexpr_on_lambda);

1315 const char *PrevSpec = nullptr;

1316 unsigned DiagID = 0;

1318 DiagID);

1319 assert(PrevSpec == nullptr && DiagID == 0 &&

1320 "Constexpr cannot have been set previously!");

1321 }

1322}

1323

1327 if (ConstevalLoc.isValid()) {

1328 P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval);

1329 const char *PrevSpec = nullptr;

1330 unsigned DiagID = 0;

1332 DiagID);

1333 if (DiagID != 0)

1334 P.Diag(ConstevalLoc, DiagID) << PrevSpec;

1335 }

1336}

1337

1343 return;

1344

1345

1346

1347

1348

1349 if (MutableLoc.isValid())

1350 P.Diag(StaticLoc, diag::err_static_mutable_lambda);

1352 P.Diag(StaticLoc, diag::err_static_lambda_captures);

1353 }

1354}

1355

1356

1357

1358ExprResult Parser::ParseLambdaExpressionAfterIntroducer(

1362 Diag(LambdaBeginLoc, diag::ext_hlsl_lambda) << 1;

1363 else

1365 ? diag::warn_cxx98_compat_lambda

1366 : diag::ext_lambda)

1367 << 0;

1368

1370 "lambda expression parsing");

1371

1372

1375 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);

1376

1380

1383

1386

1387

1388

1389

1390

1391 while (true) {

1392 if (Tok.is(tok::kw___noinline__)) {

1395 Attributes.addNew(AttrName, AttrNameLoc, nullptr,

1396 AttrNameLoc, nullptr,

1397 0, tok::kw___noinline__);

1398 } else if (Tok.is(tok::kw___attribute))

1399 ParseGNUAttributes(Attributes, nullptr, &D);

1400 else

1401 break;

1402 }

1403

1404 D.takeAttributes(Attributes);

1405 }

1406

1407 MultiParseScope TemplateParamScope(*this);

1408 if (Tok.is(tok::less)) {

1410 ? diag::warn_cxx17_compat_lambda_template_parameter_list

1411 : diag::ext_lambda_template_parameter_list);

1412

1415 if (ParseTemplateParameters(TemplateParamScope,

1416 CurTemplateDepthTracker.getDepth(),

1417 TemplateParams, LAngleLoc, RAngleLoc)) {

1420 }

1421

1422 if (TemplateParams.empty()) {

1423 Diag(RAngleLoc,

1424 diag::err_lambda_template_parameter_list_empty);

1425 } else {

1426

1427

1428

1429

1430

1431

1432

1433

1434

1435 ++CurTemplateDepthTracker;

1438 RequiresClause =

1440 false));

1443 }

1444

1446 Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause);

1447 }

1448 }

1449

1450

1451

1452

1453

1454 if (isCXX11AttributeSpecifier()) {

1456 ? diag::warn_cxx20_compat_decl_attrs_on_lambda

1457 : diag::ext_decl_attrs_on_lambda)

1459 MaybeParseCXX11Attributes(D);

1460 }

1461

1466 bool HasParentheses = false;

1467 bool HasSpecifiers = false;

1469

1473

1474

1477

1478 if (Tok.is(tok::l_paren)) {

1480 T.consumeOpen();

1481 LParenLoc = T.getOpenLocation();

1482

1483 if (Tok.isNot(tok::r_paren)) {

1485 CurTemplateDepthTracker.getOriginalDepth());

1486

1487 ParseParameterDeclarationClause(D, Attributes, ParamInfo, EllipsisLoc);

1488

1489

1490

1491

1492

1494 CurTemplateDepthTracker.setAddedDepth(1);

1495 }

1496

1497 T.consumeClose();

1498 DeclEndLoc = RParenLoc = T.getCloseLocation();

1499 HasParentheses = true;

1500 }

1501

1502 HasSpecifiers =

1503 Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,

1504 tok::kw_constexpr, tok::kw_consteval, tok::kw_static,

1505 tok::kw___private, tok::kw___global, tok::kw___local,

1506 tok::kw___constant, tok::kw___generic, tok::kw_groupshared,

1507 tok::kw_requires, tok::kw_noexcept) ||

1509 (Tok.is(tok::l_square) && NextToken().is(tok::l_square));

1510

1511 if (HasSpecifiers && !HasParentheses && getLangOpts().CPlusPlus23) {

1512

1513

1514

1515 Diag(Tok, diag::ext_lambda_missing_parens)

1517 }

1518

1519 if (HasParentheses || HasSpecifiers) {

1520

1521

1522

1523 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes);

1524

1525

1529

1531 ConstevalLoc, DeclEndLoc);

1532

1534

1538 }

1539

1541

1542 if (!HasParentheses)

1544

1545 if (HasSpecifiers || HasParentheses) {

1546

1553

1554 ESpecType = tryParseExceptionSpecification(

1555 false, ESpecRange, DynamicExceptions,

1556 DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens);

1557

1559 DeclEndLoc = ESpecRange.getEnd();

1560

1561

1562 if (MaybeParseCXX11Attributes(Attributes))

1563 DeclEndLoc = Attributes.Range.getEnd();

1564

1565

1566 if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local,

1567 tok::kw___constant, tok::kw___generic)) {

1568 ParseOpenCLQualifiers(DS.getAttributes());

1570 }

1571

1573

1574

1575 if (Tok.is(tok::arrow)) {

1578 TrailingReturnType =

1579 ParseTrailingReturnType(Range, false);

1583 }

1584

1587 true,

1588 false, LParenLoc, ParamInfo.data(),

1589 ParamInfo.size(), EllipsisLoc, RParenLoc,

1590 true,

1591 NoLoc, MutableLoc, ESpecType,

1592 ESpecRange, DynamicExceptions.data(),

1593 DynamicExceptionRanges.data(), DynamicExceptions.size(),

1594 NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,

1595 nullptr,

1596 {}, LParenLoc, FunLocalRangeEnd, D,

1597 TrailingReturnType, TrailingReturnTypeLoc, &DS),

1598 std::move(Attributes), DeclEndLoc);

1599

1600

1601

1602 if (HasParentheses)

1604

1605 if (HasParentheses && Tok.is(tok::kw_requires))

1606 ParseTrailingRequiresClause(D);

1607 }

1608

1609

1610

1612 for (const ParsedAttr &A : Attributes)

1613 if (A.getKind() == ParsedAttr::AT_CUDADevice ||

1614 A.getKind() == ParsedAttr::AT_CUDAHost ||

1615 A.getKind() == ParsedAttr::AT_CUDAGlobal)

1616 Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)

1617 << A.getAttrName()->getName();

1618 }

1619

1621

1622

1623

1626 ParseScope BodyScope(this, ScopeFlags);

1627

1629

1630

1631 if (!Tok.is(tok::l_brace)) {

1632 Diag(Tok, diag::err_expected_lambda_body);

1635 }

1636

1638 BodyScope.Exit();

1639 TemplateParamScope.Exit();

1640 LambdaScope.Exit();

1641

1642 if (Stmt.isInvalid() && !TrailingReturnType.isInvalid() &&

1643 D.isInvalidType())

1645

1648}

1649

1650

1651

1652

1653

1654

1655

1656

1657

1658

1659

1660

1663 const char *CastName = nullptr;

1664

1665 switch (Kind) {

1666 default: llvm_unreachable("Unknown C++ cast!");

1667 case tok::kw_addrspace_cast: CastName = "addrspace_cast"; break;

1668 case tok::kw_const_cast: CastName = "const_cast"; break;

1669 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;

1670 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;

1671 case tok::kw_static_cast: CastName = "static_cast"; break;

1672 }

1673

1676

1677

1678

1679 if (Tok.is(tok::l_square) && Tok.getLength() == 2) {

1681 if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))

1682 FixDigraph(*this, PP, Tok, Next, Kind, true);

1683 }

1684

1685 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))

1687

1688

1690 ParseSpecifierQualifierList(DS, AS_none,

1691 DeclSpecContext::DSC_type_specifier);

1692

1693

1696 ParseDeclarator(DeclaratorInfo);

1697

1699

1700 if (ExpectAndConsume(tok::greater))

1701 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);

1702

1704

1705 if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))

1707

1709

1710

1711 T.consumeClose();

1712

1713 if (Result.isInvalid() && !DeclaratorInfo.isInvalidType())

1715 LAngleBracketLoc, DeclaratorInfo,

1716 RAngleBracketLoc,

1717 T.getOpenLocation(), Result.get(),

1718 T.getCloseLocation());

1719

1721}

1722

1723

1724

1725

1726

1727

1728

1729ExprResult Parser::ParseCXXTypeid() {

1730 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");

1731

1735

1736

1737 if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))

1739 LParenLoc = T.getOpenLocation();

1740

1742

1743

1744

1745

1746

1747

1748

1749

1750

1751

1752

1753

1754

1755

1759

1760 if (isTypeIdInParens()) {

1762

1763

1764 T.consumeClose();

1765 RParenLoc = T.getCloseLocation();

1768

1770 Ty.get().getAsOpaquePtr(), RParenLoc);

1771 } else {

1773

1774

1775 if (Result.isInvalid())

1777 else {

1778 T.consumeClose();

1779 RParenLoc = T.getCloseLocation();

1782

1784 Result.get(), RParenLoc);

1785 }

1786 }

1787

1789}

1790

1791

1792

1793

1794

1795

1796ExprResult Parser::ParseCXXUuidof() {

1797 assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");

1798

1801

1802

1803 if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))

1805

1807

1808 if (isTypeIdInParens()) {

1810

1811

1812 T.consumeClose();

1813

1816

1818 Ty.get().getAsOpaquePtr(),

1819 T.getCloseLocation());

1820 } else {

1824

1825

1826 if (Result.isInvalid())

1828 else {

1829 T.consumeClose();

1830

1832 false,

1833 Result.get(), T.getCloseLocation());

1834 }

1835 }

1836

1838}

1839

1840

1841

1842

1843

1844

1845

1846

1847

1848

1849

1850

1851

1852

1853

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863

1864

1865

1866

1867

1868

1869

1870

1876

1877

1880 if (Tok.is(tok::identifier)) {

1883 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");

1885 } else if (Tok.is(tok::annot_template_id)) {

1887

1891 ConsumeAnnotationToken();

1892 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");

1894 } else {

1895 assert(SS.isEmpty() && "missing last component of nested name specifier");

1897 }

1898

1899

1900 assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");

1902

1903 if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid()) {

1905 ParseDecltypeSpecifier(DS);

1906 if (DS.getTypeSpecType() == TST_error)

1909 TildeLoc, DS);

1910 }

1911

1912 if (!Tok.is(tok::identifier)) {

1913 Diag(Tok, diag::err_destructor_tilde_identifier);

1915 }

1916

1917

1918 if (GetLookAheadToken(1).is(tok::ellipsis) &&

1919 GetLookAheadToken(2).is(tok::l_square)) {

1921 ParsePackIndexingType(DS);

1923 TildeLoc, DS);

1924 }

1925

1926

1931

1932

1933

1934

1935

1936

1937

1938

1939

1940 if (Tok.is(tok::less) &&

1941 ParseUnqualifiedIdTemplateId(

1943 Name, NameLoc, false, SecondTypeName,

1944 true))

1946

1948 SS, FirstTypeName, CCLoc, TildeLoc,

1949 SecondTypeName);

1950}

1951

1952

1953

1954

1955

1956

1957ExprResult Parser::ParseCXXBoolLiteral() {

1960}

1961

1962

1963

1964

1965

1966ExprResult Parser::ParseThrowExpression() {

1967 assert(Tok.is(tok::kw_throw) && "Not throw!");

1969

1970

1971

1972

1973 switch (Tok.getKind()) {

1974 case tok:🚛

1975 case tok::r_paren:

1976 case tok::r_square:

1977 case tok::r_brace:

1978 case tok::colon:

1979 case tok::comma:

1981

1982 default:

1984 if (Expr.isInvalid()) return Expr;

1986 }

1987}

1988

1989

1990

1991

1992

1993ExprResult Parser::ParseCoyieldExpression() {

1994 assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");

1995

1997 ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer()

1999 if (Expr.isInvalid())

2001 return Expr;

2002}

2003

2004

2005

2006

2007

2008

2010 assert(Tok.is(tok::kw_this) && "Not 'this'!");

2013}

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

2027

2029Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {

2033

2034 assert((Tok.is(tok::l_paren) ||

2036 && "Expected '(' or '{'!");

2037

2038 if (Tok.is(tok::l_brace)) {

2041 if (Init.isInvalid())

2042 return Init;

2043 Expr *InitList = Init.get();

2046 InitList->getEndLoc(), true);

2047 } else {

2049 T.consumeOpen();

2050

2052

2053 ExprVector Exprs;

2054

2055 auto RunSignatureHelp = [&]() {

2057 if (TypeRep)

2058 PreferredType =

2061 Exprs, T.getOpenLocation(), false);

2062 CalledSignatureHelp = true;

2063 return PreferredType;

2064 };

2065

2066 if (Tok.isNot(tok::r_paren)) {

2067 if (ParseExpressionList(Exprs, [&] {

2068 PreferredType.enterFunctionArgument(Tok.getLocation(),

2069 RunSignatureHelp);

2070 })) {

2072 RunSignatureHelp();

2075 }

2076 }

2077

2078

2079 T.consumeClose();

2080

2081

2082 if (!TypeRep)

2084

2086 Exprs, T.getCloseLocation(),

2087 false);

2088 }

2089}

2090

2092Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,

2094 assert(Tok.is(tok::kw_using) && "Expected using");

2097 "Unexpected Declarator Context");

2100

2101 DG = ParseUsingDeclaration(Context, {}, DeclStart, DeclEnd, Attrs, AS_none);

2102 if (!DG)

2103 return DG;

2104

2106 ? diag::ext_alias_in_init_statement

2107 : diag::warn_cxx20_alias_in_init_statement)

2109

2110 return DG;

2111}

2112

2113

2114

2115

2116

2117

2118

2119

2120

2121

2122

2123

2124

2125

2126

2127

2128

2129

2130

2131

2132

2133

2134

2135

2136

2137

2138

2139

2140

2141

2142

2143

2147 ForRangeInfo *FRI, bool EnterForConditionScope) {

2148

2149 struct ForConditionScopeRAII {

2151 void enter(bool IsConditionVariable) {

2152 if (S) {

2154 S->setIsConditionVarScope(IsConditionVariable);

2155 }

2156 }

2157 ~ForConditionScopeRAII() {

2158 if (S)

2159 S->setIsConditionVarScope(false);

2160 }

2161 } ForConditionScope{EnterForConditionScope ? getCurScope() : nullptr};

2162

2164 PreferredType.enterCondition(Actions, Tok.getLocation());

2165

2166 if (Tok.is(tok::code_completion)) {

2167 cutOffParsing();

2171 }

2172

2174 MaybeParseCXX11Attributes(attrs);

2175

2176 const auto WarnOnInit = [this, &CK] {

2178 ? diag::warn_cxx14_compat_init_statement

2179 : diag::ext_init_statement)

2181 };

2182

2183

2184 switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) {

2185 case ConditionOrInitStatement::Expression: {

2186

2187 ForConditionScope.enter(false);

2188

2189 ProhibitAttributes(attrs);

2190

2191

2192

2193 if (InitStmt && Tok.is(tok::semi)) {

2194 WarnOnInit();

2197 Diag(SemiLoc, diag::warn_empty_init_statement)

2200 }

2203 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);

2204 }

2205

2206

2208 if (Expr.isInvalid())

2210

2211 if (InitStmt && Tok.is(tok::semi)) {

2212 WarnOnInit();

2215 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);

2216 }

2217

2219 MissingOK);

2220 }

2221

2222 case ConditionOrInitStatement::InitStmtDecl: {

2223 WarnOnInit();

2226 if (Tok.is(tok::kw_using))

2227 DG = ParseAliasDeclarationInInitStatement(

2229 else {

2232 attrs, DeclSpecAttrs, true);

2233 }

2234 *InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd);

2235 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);

2236 }

2237

2238 case ConditionOrInitStatement::ForRangeDecl: {

2239

2240

2241

2242 assert(FRI && "should not parse a for range declaration here");

2249 }

2250

2251 case ConditionOrInitStatement::ConditionDecl:

2252 case ConditionOrInitStatement::Error:

2253 break;

2254 }

2255

2256

2257 ForConditionScope.enter(true);

2258

2259

2261 ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition);

2262

2263

2265 ParseDeclarator(DeclaratorInfo);

2266

2267

2268 if (Tok.is(tok::kw_asm)) {

2270 ExprResult AsmLabel(ParseSimpleAsm( true, &Loc));

2271 if (AsmLabel.isInvalid()) {

2274 }

2275 DeclaratorInfo.setAsmLabel(AsmLabel.get());

2276 DeclaratorInfo.SetRangeEnd(Loc);

2277 }

2278

2279

2280 MaybeParseGNUAttributes(DeclaratorInfo);

2281

2282

2284 DeclaratorInfo);

2287 Decl *DeclOut = Dcl.get();

2288

2289

2290

2291 bool CopyInitialization = isTokenEqualOrEqualTypo();

2292 if (CopyInitialization)

2294

2298 diag::warn_cxx98_compat_generalized_initializer_lists);

2299 InitExpr = ParseBraceInitializer();

2300 } else if (CopyInitialization) {

2301 PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);

2303 } else if (Tok.is(tok::l_paren)) {

2304

2305 SourceLocation LParen = ConsumeParen(), RParen = LParen;

2307 RParen = ConsumeParen();

2309 diag::err_expected_init_in_condition_lparen)

2311 } else {

2312 Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);

2313 }

2314

2317 else

2319

2322}

2323

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346

2347

2348

2349

2350void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {

2352 const char *PrevSpec;

2353 unsigned DiagID;

2357

2358 switch (Tok.getKind()) {

2359 case tok::identifier:

2360 case tok::coloncolon:

2361 llvm_unreachable("Annotation token should already be formed!");

2362 default:

2363 llvm_unreachable("Not a simple-type-specifier token!");

2364

2365

2366 case tok::annot_typename: {

2370 ConsumeAnnotationToken();

2371 DS.Finish(Actions, Policy);

2372 return;

2373 }

2374

2375 case tok::kw__ExtInt:

2376 case tok::kw__BitInt: {

2377 DiagnoseBitIntUse(Tok);

2378 ExprResult ER = ParseExtIntegerArgument();

2381 else

2383

2384

2386 DS.Finish(Actions, Policy);

2387 return;

2388 }

2389

2390

2391 case tok::kw_short:

2393 Policy);

2394 break;

2395 case tok::kw_long:

2397 Policy);

2398 break;

2399 case tok::kw___int64:

2401 Policy);

2402 break;

2403 case tok::kw_signed:

2405 break;

2406 case tok::kw_unsigned:

2408 break;

2409 case tok::kw_void:

2411 break;

2412 case tok::kw_auto:

2414 break;

2415 case tok::kw_char:

2417 break;

2418 case tok::kw_int:

2420 break;

2421 case tok::kw___int128:

2423 break;

2424 case tok::kw___bf16:

2426 break;

2427 case tok::kw_half:

2429 break;

2430 case tok::kw_float:

2432 break;

2433 case tok::kw_double:

2435 break;

2436 case tok::kw__Float16:

2438 break;

2439 case tok::kw___float128:

2441 break;

2442 case tok::kw___ibm128:

2444 break;

2445 case tok::kw_wchar_t:

2447 break;

2448 case tok::kw_char8_t:

2450 break;

2451 case tok::kw_char16_t:

2453 break;

2454 case tok::kw_char32_t:

2456 break;

2457 case tok::kw_bool:

2459 break;

2460 case tok::kw__Accum:

2462 break;

2463 case tok::kw__Fract:

2465 break;

2466 case tok::kw__Sat:

2468 break;

2469#define GENERIC_IMAGE_TYPE(ImgType, Id) \

2470 case tok::kw_##ImgType##_t: \

2471 DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \

2472 Policy); \

2473 break;

2474#include "clang/Basic/OpenCLImageTypes.def"

2475#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \

2476 case tok::kw_##Name: \

2477 DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, DiagID, Policy); \

2478 break;

2479#include "clang/Basic/HLSLIntangibleTypes.def"

2480

2481 case tok::annot_decltype:

2482 case tok::kw_decltype:

2483 DS.SetRangeEnd(ParseDecltypeSpecifier(DS));

2484 return DS.Finish(Actions, Policy);

2485

2486 case tok::annot_pack_indexing_type:

2487 DS.SetRangeEnd(ParsePackIndexingType(DS));

2488 return DS.Finish(Actions, Policy);

2489

2490

2491 case tok::kw_typeof:

2492 ParseTypeofSpecifier(DS);

2493 DS.Finish(Actions, Policy);

2494 return;

2495 }

2498 DS.Finish(Actions, Policy);

2499}

2500

2501

2502

2503

2504

2505

2506

2507

2508

2509

2510

2511

2513 ParseSpecifierQualifierList(DS, AS_none,

2514 getDeclSpecContextFromDeclaratorContext(Context));

2516 return false;

2517}

2518

2519

2520

2521

2522

2523

2524

2525

2526

2527

2528

2529

2530

2531

2532

2533

2534

2535

2536

2537

2538

2539

2540

2541

2542

2543

2544

2545

2546

2547

2548

2549

2550

2551

2552

2553

2554bool Parser::ParseUnqualifiedIdTemplateId(

2557 bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId) {

2558 assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");

2559

2562 switch (Id.getKind()) {

2566 if (AssumeTemplateId) {

2567

2568

2570 ObjectType, EnteringContext, Template,

2571 true);

2572 } else {

2573 bool MemberOfUnknownSpecialization;

2576 ObjectType, EnteringContext, Template,

2577 MemberOfUnknownSpecialization);

2578

2579

2580

2582 isTemplateArgumentList(0) == TPResult::False)

2583 return false;

2584

2585 if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&

2586 ObjectType && isTemplateArgumentList(0) == TPResult::True) {

2587

2588

2589 if (!ObjectHadErrors) {

2590

2591

2592

2593

2594 std::string Name;

2596 Name = std::string(Id.Identifier->getName());

2597 else {

2598 Name = "operator ";

2601 else

2602 Name += Id.Identifier->getName();

2603 }

2604 Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)

2605 << Name

2607 }

2609 getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext,

2610 Template, true);

2612 return false;

2613 }

2614 }

2615 break;

2616

2619 bool MemberOfUnknownSpecialization;

2623 EnteringContext, Template,

2624 MemberOfUnknownSpecialization);

2626 return false;

2627 break;

2628 }

2629

2632 bool MemberOfUnknownSpecialization;

2634 if (ObjectType) {

2637 EnteringContext, Template, true);

2638 } else {

2641 EnteringContext, Template,

2642 MemberOfUnknownSpecialization);

2643

2645 Diag(NameLoc, diag::err_destructor_template_id)

2647

2648 }

2649 }

2650 break;

2651 }

2652

2653 default:

2654 return false;

2655 }

2656

2657

2659 TemplateArgList TemplateArgs;

2660 if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, RAngleLoc,

2661 Template))

2662 return true;

2663

2664

2666 return true;

2667

2671

2672

2673

2674

2677 : nullptr;

2681 : Id.OperatorFunctionId.Operator;

2682

2684 TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,

2685 LAngleLoc, RAngleLoc, TemplateArgs, false, TemplateIds);

2686

2687 Id.setTemplateId(TemplateId);

2688 return false;

2689 }

2690

2691

2693

2694

2696 getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc,

2697 TemplateArgsPtr, RAngleLoc, true);

2698 if (Type.isInvalid())

2699 return true;

2700

2702 Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);

2703 else

2704 Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);

2705

2706 return false;

2707}

2708

2709

2710

2711

2712

2713

2714

2715

2716

2717

2718

2719

2720

2721

2722

2723

2724

2725

2726

2727

2728

2729

2730

2731

2732

2733

2734

2735

2736

2737

2738

2739

2740

2741

2742

2743

2744

2745

2746

2747

2748

2749bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,

2752 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");

2753

2754

2756

2757

2758 unsigned SymbolIdx = 0;

2761 switch (Tok.getKind()) {

2762 case tok::kw_new:

2763 case tok::kw_delete: {

2764 bool isNew = Tok.getKind() == tok::kw_new;

2765

2766 SymbolLocations[SymbolIdx++] = ConsumeToken();

2767

2768 if (Tok.is(tok::l_square) &&

2770

2772 T.consumeOpen();

2773 T.consumeClose();

2774 if (T.getCloseLocation().isInvalid())

2775 return true;

2776

2777 SymbolLocations[SymbolIdx++] = T.getOpenLocation();

2778 SymbolLocations[SymbolIdx++] = T.getCloseLocation();

2779 Op = isNew? OO_Array_New : OO_Array_Delete;

2780 } else {

2781 Op = isNew? OO_New : OO_Delete;

2782 }

2783 break;

2784 }

2785

2786#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \

2787 case tok::Token: \

2788 SymbolLocations[SymbolIdx++] = ConsumeToken(); \

2789 Op = OO_##Name; \

2790 break;

2791#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)

2792#include "clang/Basic/OperatorKinds.def"

2793

2794 case tok::l_paren: {

2795

2797 T.consumeOpen();

2798 T.consumeClose();

2799 if (T.getCloseLocation().isInvalid())

2800 return true;

2801

2802 SymbolLocations[SymbolIdx++] = T.getOpenLocation();

2803 SymbolLocations[SymbolIdx++] = T.getCloseLocation();

2804 Op = OO_Call;

2805 break;

2806 }

2807

2808 case tok::l_square: {

2809

2811 T.consumeOpen();

2812 T.consumeClose();

2813 if (T.getCloseLocation().isInvalid())

2814 return true;

2815

2816 SymbolLocations[SymbolIdx++] = T.getOpenLocation();

2817 SymbolLocations[SymbolIdx++] = T.getCloseLocation();

2818 Op = OO_Subscript;

2819 break;

2820 }

2821

2822 case tok::code_completion: {

2823

2824 cutOffParsing();

2825

2827 return true;

2828 }

2829

2830 default:

2831 break;

2832 }

2833

2835

2836 Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);

2837 return false;

2838 }

2839

2840

2841

2842

2843

2844

2845

2847 Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);

2848

2850 unsigned DiagId = 0;

2851

2852

2853

2856 while (isTokenStringLiteral()) {

2857 if (!Tok.is(tok::string_literal) && !DiagId) {

2858

2859

2860

2862 DiagId = diag::err_literal_operator_string_prefix;

2863 }

2864 Toks.push_back(Tok);

2865 TokLocs.push_back(ConsumeStringToken());

2866 }

2867

2870 return true;

2871

2872

2873

2874 bool IsUDSuffix = Literal.getUDSuffix().empty();

2877 if (IsUDSuffix) {

2879 SuffixLoc =

2881 Literal.getUDSuffixOffset(),

2883 } else if (Tok.is(tok::identifier)) {

2886 TokLocs.push_back(SuffixLoc);

2887 } else {

2888 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

2889 return true;

2890 }

2891

2892

2893 if (Literal.GetString().empty() || Literal.Pascal) {

2894

2895

2896

2897

2898 DiagLoc = TokLocs.front();

2899 DiagId = diag::err_literal_operator_string_not_empty;

2900 }

2901

2902 if (DiagId) {

2903

2904

2906 Str += "\"\"";

2909 SourceRange(TokLocs.front(), TokLocs.back()), Str);

2910 }

2911

2912 Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);

2913

2915 }

2916

2917

2918

2919

2920

2921

2922

2923

2924

2925

2926

2927

2928

2930 if (ParseCXXTypeSpecifierSeq(

2932 return true;

2933

2934

2935

2938 ParseDeclaratorInternal(D, nullptr);

2939

2940

2943 return true;

2944

2945

2946 Result.setConversionFunctionId(KeywordLoc, Ty.get(),

2948 return false;

2949}

2950

2951

2952

2953

2954

2955

2956

2957

2958

2959

2960

2961

2962

2963

2964

2965

2966

2967

2968

2969

2970

2971

2972

2973

2974

2975

2976

2977

2978

2979

2980

2981

2982

2983

2984

2985

2986

2988 bool ObjectHadErrors, bool EnteringContext,

2989 bool AllowDestructorName,

2990 bool AllowConstructorName,

2991 bool AllowDeductionGuide,

2994 if (TemplateKWLoc)

2996

2997

2998

2999 bool TemplateSpecified = false;

3000 if (Tok.is(tok::kw_template)) {

3001 if (TemplateKWLoc && (ObjectType || SS.isSet())) {

3002 TemplateSpecified = true;

3004 } else {

3006 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)

3008 }

3009 }

3010

3011

3012

3013

3014 if (Tok.is(tok::identifier)) {

3015 ParseIdentifier:

3016

3019

3021

3022

3023 Result.setIdentifier(Id, IdLoc);

3024 return false;

3025 }

3026

3028 if (AllowConstructorName &&

3030

3032 EnteringContext);

3033 if (!Ty)

3034 return true;

3035 Result.setConstructorName(Ty, IdLoc, IdLoc);

3040

3042 } else {

3043

3044 Result.setIdentifier(Id, IdLoc);

3045 }

3046

3047

3049 if (Tok.is(tok::less))

3050 return ParseUnqualifiedIdTemplateId(

3051 SS, ObjectType, ObjectHadErrors,

3052 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,

3053 EnteringContext, Result, TemplateSpecified);

3054

3055 if (TemplateSpecified) {

3058 ObjectType, EnteringContext, Template,

3059 true);

3061 return true;

3062

3063

3064

3065

3068 !Tok.is(tok::less))

3069 Diag(IdLoc, diag::missing_template_arg_list_after_template_kw);

3070 }

3071 return false;

3072 }

3073

3074

3075

3076 if (Tok.is(tok::annot_template_id)) {

3078

3079

3080

3082 ConsumeAnnotationToken();

3083 return true;

3084 }

3085

3086

3087 if (AllowConstructorName && TemplateId->Name &&

3089 if (SS.isSet()) {

3090

3091

3092

3093

3095 diag::err_out_of_line_constructor_template_id)

3096 << TemplateId->Name

3101 EnteringContext);

3102 if (!Ty)

3103 return true;

3106 ConsumeAnnotationToken();

3107 return false;

3108 }

3109

3110 Result.setConstructorTemplateId(TemplateId);

3111 ConsumeAnnotationToken();

3112 return false;

3113 }

3114

3115

3116

3117 Result.setTemplateId(TemplateId);

3119 if (TemplateLoc.isValid()) {

3120 if (TemplateKWLoc && (ObjectType || SS.isSet()))

3121 *TemplateKWLoc = TemplateLoc;

3122 else

3123 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)

3125 }

3126 ConsumeAnnotationToken();

3127 return false;

3128 }

3129

3130

3131

3132

3133 if (Tok.is(tok::kw_operator)) {

3134 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))

3135 return true;

3136

3137

3138

3139

3140

3141

3145 Tok.is(tok::less))

3146 return ParseUnqualifiedIdTemplateId(

3147 SS, ObjectType, ObjectHadErrors,

3148 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr,

3150 else if (TemplateSpecified &&

3153 EnteringContext, Template,

3155 return true;

3156

3157 return false;

3158 }

3159

3161 (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {

3162

3163

3164

3165

3166

3167

3169

3170 if (TemplateSpecified) {

3171

3172

3173

3174

3175

3176

3177

3178

3179

3180

3181 Diag(*TemplateKWLoc, diag::err_unexpected_template_in_destructor_name)

3183 return true;

3184 }

3185

3186 if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {

3191 Result.setDestructorName(TildeLoc, Type, EndLoc);

3192 return false;

3193 }

3194 return true;

3195 }

3196

3197

3198 if (Tok.isNot(tok::identifier)) {

3199 Diag(Tok, diag::err_destructor_tilde_identifier);

3200 return true;

3201 }

3202

3203

3204 DeclaratorScopeObj DeclScopeObj(*this, SS);

3205 if (NextToken().is(tok::coloncolon)) {

3206

3207

3208

3210

3211 if (SS.isSet()) {

3212 AnnotateScopeToken(SS, true);

3214 }

3215 if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, ObjectHadErrors,

3216 EnteringContext))

3217 return true;

3219 ObjectType = nullptr;

3220 if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) ||

3222 Diag(TildeLoc, diag::err_destructor_tilde_scope);

3223 return true;

3224 }

3225

3226

3227 Diag(TildeLoc, diag::err_destructor_tilde_scope)

3230

3231

3233 DeclScopeObj.EnterDeclaratorScope();

3234 }

3235

3236

3239

3240 if (Tok.is(tok::less)) {

3241 Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc);

3242 return ParseUnqualifiedIdTemplateId(

3243 SS, ObjectType, ObjectHadErrors,

3244 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName,

3245 ClassNameLoc, EnteringContext, Result, TemplateSpecified);

3246 }

3247

3248

3251 ObjectType, EnteringContext);

3252 if (!Ty)

3253 return true;

3254

3255 Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);

3256 return false;

3257 }

3258

3259 switch (Tok.getKind()) {

3260#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:

3261#include "clang/Basic/TransformTypeTraits.def"

3262 if (NextToken().is(tok::l_paren)) {

3263 Tok.setKind(tok::identifier);

3264 Diag(Tok, diag::ext_keyword_as_ident)

3266 goto ParseIdentifier;

3267 }

3268 [[fallthrough]];

3269 default:

3270 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;

3271 return true;

3272 }

3273}

3274

3275

3276

3277

3278

3279

3280

3281

3282

3283

3284

3285

3286

3287

3288

3289

3290

3291

3292

3293

3294

3295

3296

3297

3298

3299

3300

3301

3302

3304Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {

3305 assert(Tok.is(tok::kw_new) && "expected 'new' token");

3307

3308

3309

3310

3311 ExprVector PlacementArgs;

3313

3318 if (Tok.is(tok::l_paren)) {

3319

3321 T.consumeOpen();

3322 PlacementLParen = T.getOpenLocation();

3323 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {

3326 }

3327

3328 T.consumeClose();

3329 PlacementRParen = T.getCloseLocation();

3330 if (PlacementRParen.isInvalid()) {

3333 }

3334

3335 if (PlacementArgs.empty()) {

3336

3337 TypeIdParens = T.getRange();

3338 PlacementLParen = PlacementRParen = SourceLocation();

3339 } else {

3340

3341 if (Tok.is(tok::l_paren)) {

3343 T.consumeOpen();

3344 MaybeParseGNUAttributes(DeclaratorInfo);

3345 ParseSpecifierQualifierList(DS);

3347 ParseDeclarator(DeclaratorInfo);

3348 T.consumeClose();

3349 TypeIdParens = T.getRange();

3350 } else {

3351 MaybeParseGNUAttributes(DeclaratorInfo);

3352 if (ParseCXXTypeSpecifierSeq(DS))

3353 DeclaratorInfo.setInvalidType(true);

3354 else {

3356 ParseDeclaratorInternal(DeclaratorInfo,

3357 &Parser::ParseDirectNewDeclarator);

3358 }

3359 }

3360 }

3361 } else {

3362

3363

3364 MaybeParseGNUAttributes(DeclaratorInfo);

3366 DeclaratorInfo.setInvalidType(true);

3367 else {

3369 ParseDeclaratorInternal(DeclaratorInfo,

3370 &Parser::ParseDirectNewDeclarator);

3371 }

3372 }

3373 if (DeclaratorInfo.isInvalidType()) {

3376 }

3377

3379

3380 if (Tok.is(tok::l_paren)) {

3381 SourceLocation ConstructorLParen, ConstructorRParen;

3382 ExprVector ConstructorArgs;

3384 T.consumeOpen();

3385 ConstructorLParen = T.getOpenLocation();

3386 if (Tok.isNot(tok::r_paren)) {

3387 auto RunSignatureHelp = [&]() {

3390

3391

3392

3393 if (TypeRep)

3394 PreferredType =

3397 DeclaratorInfo.getEndLoc(), ConstructorArgs,

3398 ConstructorLParen,

3399 false);

3400 CalledSignatureHelp = true;

3401 return PreferredType;

3402 };

3403 if (ParseExpressionList(ConstructorArgs, [&] {

3404 PreferredType.enterFunctionArgument(Tok.getLocation(),

3405 RunSignatureHelp);

3406 })) {

3408 RunSignatureHelp();

3411 }

3412 }

3413 T.consumeClose();

3414 ConstructorRParen = T.getCloseLocation();

3415 if (ConstructorRParen.isInvalid()) {

3418 }

3420 ConstructorRParen,

3421 ConstructorArgs);

3424 diag::warn_cxx98_compat_generalized_initializer_lists);

3426 }

3429

3430 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,

3431 PlacementArgs, PlacementRParen,

3432 TypeIdParens, DeclaratorInfo, Initializer.get());

3433}

3434

3435

3436

3437

3438

3439

3440

3441

3442void Parser::ParseDirectNewDeclarator(Declarator &D) {

3443

3444 bool First = true;

3445 while (Tok.is(tok::l_square)) {

3446

3447 if (CheckProhibitedCXX11Attribute())

3448 continue;

3449

3451 T.consumeOpen();

3452

3456 if (Size.isInvalid()) {

3457

3459 return;

3460 }

3462

3463 T.consumeClose();

3464

3465

3467 MaybeParseCXX11Attributes(Attrs);

3468

3470 false, false,

3471 Size.get(), T.getOpenLocation(),

3472 T.getCloseLocation()),

3473 std::move(Attrs), T.getCloseLocation());

3474

3475 if (T.getCloseLocation().isInvalid())

3476 return;

3477 }

3478}

3479

3480

3481

3482

3483

3484

3485

3486

3487

3488

3489

3490bool Parser::ParseExpressionListOrTypeId(

3493

3494 if (isTypeIdInParens()) {

3495 ParseSpecifierQualifierList(D.getMutableDeclSpec());

3497 ParseDeclarator(D);

3498 return D.isInvalidType();

3499 }

3500

3501

3502 return ParseExpressionList(PlacementArgs);

3503}

3504

3505

3506

3507

3508

3509

3510

3511

3512

3513

3514

3515

3517Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {

3518 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");

3520

3521

3522 bool ArrayDelete = false;

3523 if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {

3524

3525

3526

3527

3528

3529

3530

3531 const Token Next = GetLookAheadToken(2);

3532

3533

3534 if (Next.isOneOf(tok::l_brace, tok::less) ||

3535 (Next.is(tok::l_paren) &&

3536 (GetLookAheadToken(3).is(tok::r_paren) ||

3537 (GetLookAheadToken(3).is(tok::identifier) &&

3538 GetLookAheadToken(4).is(tok::identifier))))) {

3539 TentativeParsingAction TPA(*this);

3542

3543

3544

3547 bool EmitFixIt = false;

3548 if (Tok.is(tok::l_brace)) {

3549 ConsumeBrace();

3552 EmitFixIt = true;

3553 }

3554

3555 TPA.Revert();

3556

3557 if (EmitFixIt)

3558 Diag(Start, diag::err_lambda_after_delete)

3564 ")");

3565 else

3566 Diag(Start, diag::err_lambda_after_delete)

3568

3569

3570

3571 ExprResult Lambda = ParseLambdaExpression();

3574

3575

3576 Lambda = ParsePostfixExpressionSuffix(Lambda);

3579 return Actions.ActOnCXXDelete(Start, UseGlobal, false,

3580 Lambda.get());

3581 }

3582

3583 ArrayDelete = true;

3585

3586 T.consumeOpen();

3587 T.consumeClose();

3588 if (T.getCloseLocation().isInvalid())

3590 }

3591

3593 if (Operand.isInvalid())

3595

3597}

3598

3599

3600

3601

3602

3603

3604

3605

3606

3607

3608

3609

3610

3611

3612

3613

3614

3615

3616

3617

3618

3619

3620

3621

3622

3623ExprResult Parser::ParseRequiresExpression() {

3624 assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");

3626

3629 if (Tok.is(tok::l_paren)) {

3630

3633 Parens.consumeOpen();

3634 if (!Tok.is(tok::r_paren)) {

3639 FirstArgAttrs, LocalParameters,

3640 EllipsisLoc);

3641 if (EllipsisLoc.isValid())

3642 Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis);

3643 for (auto &ParamInfo : LocalParameters)

3644 LocalParameterDecls.push_back(cast(ParamInfo.Param));

3645 }

3646 Parens.consumeClose();

3647 }

3648

3650 if (Braces.expectAndConsume())

3652

3653

3655

3656

3657

3660

3662

3663

3664

3667 RequiresKWLoc, LocalParameterDecls, getCurScope());

3668

3669 if (Tok.is(tok::r_brace)) {

3670

3671

3672

3673

3674

3675

3676 Diag(Tok, diag::err_empty_requires_expr);

3677

3678 } else {

3679 while (!Tok.is(tok::r_brace)) {

3680 switch (Tok.getKind()) {

3681 case tok::l_brace: {

3682

3683

3684

3685

3686

3687

3688

3689

3690

3692 ExprBraces.consumeOpen();

3696 ExprBraces.skipToEnd();

3698 break;

3699 }

3700 if (ExprBraces.consumeClose())

3701 ExprBraces.skipToEnd();

3702

3706 if (Tok.is(tok::semi)) {

3708 if (Req)

3709 Requirements.push_back(Req);

3710 break;

3711 }

3713

3714 Diag(Tok, diag::err_requires_expr_missing_arrow)

3716

3717 if (TryAnnotateTypeConstraint()) {

3719 break;

3720 }

3721 if (!isTypeConstraintAnnotation()) {

3722 Diag(Tok, diag::err_requires_expr_expected_type_constraint);

3724 break;

3725 }

3727 if (Tok.is(tok::annot_cxxscope)) {

3730 SS);

3731 ConsumeAnnotationToken();

3732 }

3733

3735 Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok),

3736 TemplateParameterDepth);

3737 ConsumeAnnotationToken();

3738 if (Req)

3739 Requirements.push_back(Req);

3740 break;

3741 }

3742 default: {

3743 bool PossibleRequiresExprInSimpleRequirement = false;

3744 if (Tok.is(tok::kw_requires)) {

3745 auto IsNestedRequirement = [&] {

3746 RevertingTentativeParsingAction TPA(*this);

3748 if (Tok.is(tok::l_brace))

3749

3750

3751

3752

3753

3754 return false;

3755 if (Tok.is(tok::l_paren)) {

3756

3757 ConsumeParen();

3758 auto Res = TryParseParameterDeclarationClause();

3759 if (Res != TPResult::False) {

3760

3761 unsigned Depth = 1;

3762 while (Depth != 0) {

3763 bool FoundParen = SkipUntil(tok::l_paren, tok::r_paren,

3765 if (!FoundParen)

3766 break;

3767 if (Tok.is(tok::l_paren))

3768 Depth++;

3769 else if (Tok.is(tok::r_paren))

3770 Depth--;

3772 }

3773

3774

3775

3776

3777

3778

3779

3780 if (Tok.is(tok::l_brace))

3781

3782

3783

3784 return false;

3785 }

3786 }

3787 return true;

3788 };

3789 if (IsNestedRequirement()) {

3791

3792

3793

3794

3798 SkipUntil(tok::semi, tok::r_brace,

3800 break;

3801 }

3802 if (auto *Req =

3804 Requirements.push_back(Req);

3805 else {

3806 SkipUntil(tok::semi, tok::r_brace,

3808 break;

3809 }

3810 break;

3811 } else

3812 PossibleRequiresExprInSimpleRequirement = true;

3813 } else if (Tok.is(tok::kw_typename)) {

3814

3815

3816 TentativeParsingAction TPA(*this);

3817

3818

3821 TPA.Commit();

3823 break;

3824 }

3826 if (Tok.is(tok::annot_cxxscope)) {

3829 ConsumeAnnotationToken();

3830 }

3831

3832 if (Tok.isOneOf(tok::identifier, tok::annot_template_id) &&

3834 TPA.Commit();

3838 if (Tok.is(tok::identifier)) {

3841 } else {

3842 TemplateId = takeTemplateIdAnnotation(Tok);

3843 ConsumeAnnotationToken();

3845 break;

3846 }

3847

3849 NameLoc, II,

3850 TemplateId)) {

3851 Requirements.push_back(Req);

3852 }

3853 break;

3854 }

3855 TPA.Revert();

3856 }

3857

3858

3859

3860

3866 break;

3867 }

3868 if (Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)

3869 Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)

3872 Requirements.push_back(Req);

3873 else {

3875 break;

3876 }

3877

3878 if (Tok.is(tok::kw_noexcept)) {

3879 Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept)

3883 break;

3884 }

3885 break;

3886 }

3887 }

3888 if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) {

3891 break;

3892 }

3893 }

3894 if (Requirements.empty()) {

3895

3896

3897

3898 Braces.consumeClose();

3901 }

3902 }

3903 Braces.consumeClose();

3905 ParsingBodyDecl.complete(Body);

3907 RequiresKWLoc, Body, Parens.getOpenLocation(), LocalParameterDecls,

3908 Parens.getCloseLocation(), Requirements, Braces.getCloseLocation());

3909}

3910

3912 switch (kind) {

3913 default: llvm_unreachable("Not a known type trait");

3914#define TYPE_TRAIT_1(Spelling, Name, Key) \

3915case tok::kw_ ## Spelling: return UTT_ ## Name;

3916#define TYPE_TRAIT_2(Spelling, Name, Key) \

3917case tok::kw_ ## Spelling: return BTT_ ## Name;

3918#include "clang/Basic/TokenKinds.def"

3919#define TYPE_TRAIT_N(Spelling, Name, Key) \

3920 case tok::kw_ ## Spelling: return TT_ ## Name;

3921#include "clang/Basic/TokenKinds.def"

3922 }

3923}

3924

3926 switch (kind) {

3927 default:

3928 llvm_unreachable("Not a known array type trait");

3929#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \

3930 case tok::kw_##Spelling: \

3931 return ATT_##Name;

3932#include "clang/Basic/TokenKinds.def"

3933 }

3934}

3935

3937 switch (kind) {

3938 default:

3939 llvm_unreachable("Not a known unary expression trait.");

3940#define EXPRESSION_TRAIT(Spelling, Name, Key) \

3941 case tok::kw_##Spelling: \

3942 return ET_##Name;

3943#include "clang/Basic/TokenKinds.def"

3944 }

3945}

3946

3947

3948

3949

3950

3951

3952

3953

3954

3955

3956

3957

3958ExprResult Parser::ParseTypeTrait() {

3960

3962

3964 if (Parens.expectAndConsume())

3966

3968 do {

3969

3977 }

3978

3979

3980 if (Tok.is(tok::ellipsis)) {

3985 }

3986 }

3987

3988

3989 Args.push_back(Ty.get());

3991

3992 if (Parens.consumeClose())

3994

3996

3998}

3999

4000

4001

4002

4003

4004

4005

4006

4007ExprResult Parser::ParseArrayTypeTrait() {

4010

4012 if (T.expectAndConsume())

4014

4021 }

4022

4023 switch (ATT) {

4024 case ATT_ArrayRank: {

4025 T.consumeClose();

4027 T.getCloseLocation());

4028 }

4029 case ATT_ArrayExtent: {

4030 if (ExpectAndConsume(tok::comma)) {

4033 }

4034

4036 T.consumeClose();

4037

4040

4042 T.getCloseLocation());

4043 }

4044 }

4045 llvm_unreachable("Invalid ArrayTypeTrait!");

4046}

4047

4048

4049

4050

4051

4052

4053

4054ExprResult Parser::ParseExpressionTrait() {

4057

4059 if (T.expectAndConsume())

4061

4063

4064 T.consumeClose();

4065

4067 T.getCloseLocation());

4068}

4069

4070

4071

4072

4073

4075Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,

4080 assert(ExprType == CastExpr && "Compound literals are not ambiguous!");

4081 assert(isTypeIdInParens() && "Not a type-id!");

4082

4084 CastTy = nullptr;

4085

4086

4087

4088

4089

4090

4091

4092

4093

4094

4095

4096

4097

4098

4099

4100

4101

4102

4103

4104

4105 ParenParseOption ParseAs;

4107

4108

4109

4110 if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {

4111

4114 }

4115

4116 if (Tok.is(tok::l_brace)) {

4117 ParseAs = CompoundLiteral;

4118 } else {

4119 bool NotCastExpr;

4120 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {

4121 NotCastExpr = true;

4122 } else {

4123

4124

4125

4127 Result = ParseCastExpression(AnyCastExpr,

4128 false,

4129 NotCastExpr,

4130

4132 }

4133

4134

4135

4136 ParseAs = NotCastExpr ? SimpleExpr : CastExpr;

4137 }

4138

4139

4142 AttrEnd.setKind(tok::eof);

4145 Toks.push_back(AttrEnd);

4146

4147

4148 Toks.push_back(Tok);

4149

4150

4151 PP.EnterTokenStream(Toks, true,

4152 true);

4153

4154

4156

4157 if (ParseAs >= CompoundLiteral) {

4158

4162 {

4164 ParseSpecifierQualifierList(DS);

4165 ParseDeclarator(DeclaratorInfo);

4166 }

4167

4168

4171

4172

4175

4176 if (ParseAs == CompoundLiteral) {

4177 ExprType = CompoundLiteral;

4178 if (DeclaratorInfo.isInvalidType())

4180

4182 return ParseCompoundLiteralExpression(Ty.get(),

4185 }

4186

4187

4188 assert(ParseAs == CastExpr);

4189

4190 if (DeclaratorInfo.isInvalidType())

4192

4193

4194 if (Result.isInvalid())

4196 DeclaratorInfo, CastTy,

4199 }

4200

4201

4202 assert(ParseAs == SimpleExpr);

4203

4204 ExprType = SimpleExpr;

4206 if (Result.isInvalid() && Tok.is(tok::r_paren))

4209

4210

4211 if (Result.isInvalid()) {

4212 while (Tok.isNot(tok::eof))

4217 }

4218

4220

4224}

4225

4226

4227ExprResult Parser::ParseBuiltinBitCast() {

4229

4231 if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast"))

4233

4234

4236 ParseSpecifierQualifierList(DS);

4237

4238

4241 ParseDeclarator(DeclaratorInfo);

4242

4243 if (ExpectAndConsume(tok::comma)) {

4244 Diag(Tok.getLocation(), diag::err_expected) << tok::comma;

4247 }

4248

4250

4251 if (T.consumeClose())

4253

4254 if (Operand.isInvalid() || DeclaratorInfo.isInvalidType())

4256

4258 T.getCloseLocation());

4259}

Defines the clang::ASTContext interface.

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

static void addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, DeclSpec &DS)

static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, Token &ColonToken, tok::TokenKind Kind, bool AtDigraph)

static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind)

static void tryConsumeLambdaSpecifierToken(Parser &P, SourceLocation &MutableLoc, SourceLocation &StaticLoc, SourceLocation &ConstexprLoc, SourceLocation &ConstevalLoc, SourceLocation &DeclEndLoc)

static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind)

static void addConstevalToLambdaDeclSpecifier(Parser &P, SourceLocation ConstevalLoc, DeclSpec &DS)

static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind)

static void DiagnoseStaticSpecifierRestrictions(Parser &P, SourceLocation StaticLoc, SourceLocation MutableLoc, const LambdaIntroducer &Intro)

static int SelectDigraphErrorMessage(tok::TokenKind Kind)

static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc, DeclSpec &DS)

Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...

static constexpr bool isOneOf()

This file declares facilities that support code completion.

Defines the clang::TemplateNameKind enum.

Defines the clang::TokenKind enum and support functions.

const clang::PrintingPolicy & getPrintingPolicy() const

RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....

SourceLocation getOpenLocation() const

SourceLocation getCloseLocation() const

Represents a C++ nested-name-specifier or a global scope specifier.

bool isNotEmpty() const

A scope specifier is present, but may be valid or invalid.

SourceRange getRange() const

SourceLocation getBeginLoc() const

bool isSet() const

Deprecated.

void setEndLoc(SourceLocation Loc)

void SetInvalid(SourceRange R)

Indicate that this nested-name-specifier is invalid.

bool isEmpty() const

No scope specifier.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.

void restore()

restore - This can be used to restore the state early, before the dtor is run.

Captures information about "declaration specifiers".

static const TST TST_typename

SourceLocation getEndLoc() const LLVM_READONLY

bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)

These methods set the specified attribute of the DeclSpec and return false if there was no error.

static const TST TST_char8

static const TST TST_BFloat16

bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)

bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)

These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...

bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)

bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)

SourceRange getSourceRange() const LLVM_READONLY

void SetRangeEnd(SourceLocation Loc)

bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)

static const TST TST_double

void SetRangeStart(SourceLocation Loc)

static const TST TST_char

static const TST TST_bool

static const TST TST_char16

static const TST TST_accum

static const TST TST_half

static const TST TST_ibm128

static const TST TST_float128

void Finish(Sema &S, const PrintingPolicy &Policy)

Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...

static const TST TST_wchar

static const TST TST_void

static const TST TST_float

static const TST TST_fract

static const TST TST_float16

static const TST TST_decltype_auto

static const TST TST_error

static const TST TST_char32

static const TST TST_int128

bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)

static const TST TST_auto

Decl - This represents one declaration (or definition), e.g.

SourceLocation getLocation() const

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

Information about one declarator, including the parsed type information and the identifier.

RAII object that enters a new expression evaluation context.

This represents one expression.

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

static FixItHint CreateRemoval(CharSourceRange RemoveRange)

Create a code modification hint that removes the given source range.

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Characters, const SourceManager &SM, const LangOptions &LangOpts)

AdvanceToTokenCharacter - If the current SourceLocation specifies a location at the start of a token,...

static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)

Computes the source location just past the end of the token at this source location.

This represents a decl that may have a name.

static OpaquePtr make(QualType P)

RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...

ParsedAttr - Represents a syntactic attribute.

static const ParsedAttributesView & none()

ParsedAttributes - A collection of parsed attributes.

Parser - This implements a parser for the C family of languages.

TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)

ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

SourceLocation ConsumeToken()

ConsumeToken - Consume the current 'peek token' and lex the next one.

AttributeFactory & getAttrFactory()

static TypeResult getTypeAnnotation(const Token &Tok)

getTypeAnnotation - Read a parsed type out of an annotation token.

ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)

Parse a constraint-logical-or-expression.

bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)

Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.

bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.

ExprResult ParseConstantExpression()

bool TryConsumeToken(tok::TokenKind Expected)

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

Scope * getCurScope() const

OpaquePtr< TemplateName > TemplateTy

bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))

SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...

ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)

Parse an expr that doesn't include (top-level) commas.

const LangOptions & getLangOpts() const

ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)

Simple precedence-based parser for binary/ternary operators.

@ StopBeforeMatch

Stop skipping at specified token, but don't skip the token itself.

@ StopAtSemi

Stop skipping at semicolon.

const Token & NextToken()

NextToken - This peeks ahead one token and returns it without consuming it.

ExprResult ParseConstraintExpression()

Parse a constraint-expression.

RAII object used to inform the actions that we're currently parsing a declaration.

void enterTypeCast(SourceLocation Tok, QualType CastType)

Handles all type casts, including C-style cast, C++ casts, etc.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

void EnterToken(const Token &Tok, bool IsReinject)

Enters a token in the token stream to be lexed next.

void AnnotateCachedTokens(const Token &Tok)

We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...

void Lex(Token &Result)

Lex the next token for this preprocessor.

const Token & LookAhead(unsigned N)

Peeks ahead N tokens and returns that token without consuming any tokens.

SourceManager & getSourceManager() const

void RevertCachedTokens(unsigned N)

When backtracking is enabled and tokens are cached, this allows to revert a specific number of tokens...

IdentifierTable & getIdentifierTable()

bool isCodeCompletionReached() const

Returns true if code-completion is enabled and we have hit the code-completion point.

SourceLocation getLastCachedTokenLocation() const

Get the location of the last cached token, suitable for setting the end location of an annotation tok...

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Computes the source location just past the end of the token at this source location.

If a crash happens while one of these objects are live, the message is printed out along with the spe...

A (possibly-)qualified type.

Represents the body of a requires-expression.

Scope - A scope is a transient data structure that is used while parsing the program.

@ FunctionPrototypeScope

This is a scope that corresponds to the parameters within a function prototype.

@ LambdaScope

This is the scope for a lambda, after the lambda introducer.

@ BlockScope

This is a scope that corresponds to a block/closure object.

@ ContinueScope

This is a while, do, for, which can have continue statements embedded into it.

@ BreakScope

This is a while, do, switch, for, etc that can have break statements embedded into it.

@ CompoundStmtScope

This is a compound statement scope.

@ FunctionDeclarationScope

This is a scope that corresponds to the parameters within a function prototype for a function declara...

@ FnScope

This indicates that the scope corresponds to a function, which means that labels are set here.

@ DeclScope

This is a scope that can contain a declaration.

void CodeCompleteObjCMessageReceiver(Scope *S)

void CodeCompleteOperatorName(Scope *S)

@ PCC_Condition

Code completion occurs within the condition of an if, while, switch, or for statement.

void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand)

QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)

void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration, QualType BaseType, QualType PreferredType)

void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)

ExprResult ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)

ActOnCXXTypeid - Parse typeid( something ).

ExprResult ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)

ActOnCXXUuidof - Parse __uuidof( something ).

ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body)

ActOnLambdaExpr - This is called when the body of a lambda expression was successfully completed.

TypeResult ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, const IdentifierInfo *TemplateII, SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, bool IsCtorOrDtorName=false, bool IsClassName=false, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)

DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D)

ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a C++ if/switch/while/for statem...

ExprResult ActOnExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)

ActOnExpressionTrait - Parsed one of the unary type trait support pseudo-functions.

@ Switch

An integral condition for a 'switch' statement.

ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)

void ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, Scope *CurContext)

Once the Lambdas capture are known, we can start to create the closure, call operator method,...

concepts::Requirement * ActOnSimpleRequirement(Expr *E)

StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)

concepts::Requirement * ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc)

bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, const DeclSpec &DS, SourceLocation ColonColonLoc)

ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand)

ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:

TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool &MemberOfUnknownSpecialization, bool Disambiguation=false)

void FinalizeDeclaration(Decl *D)

FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...

ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)

ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)

ASTContext & getASTContext() const

bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)

isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...

ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, UnqualifiedId &SecondTypeName)

ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)

ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)

ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.

void ActOnFinishRequiresExpr()

ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr)

sema::LambdaScopeInfo * getCurGenericLambda()

Retrieve the current generic lambda info, if any.

ExprResult ActOnNameClassifiedAsNonType(Scope *S, const CXXScopeSpec &SS, NamedDecl *Found, SourceLocation NameLoc, const Token &NextToken)

Act on the result of classifying a name as a specific non-type declaration.

ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)

bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS)

The parser has parsed a global nested-name-specifier '::'.

bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool *IsCorrectedToColon=nullptr, bool OnlyNamespace=false)

The parser has parsed a nested-name-specifier 'identifier::'.

bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id, bool IsUDSuffix)

ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)

sema::LambdaScopeInfo * PushLambdaScope()

SemaCodeCompletion & CodeCompletion()

void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, Declarator &ParamInfo, const DeclSpec &DS)

ActOnStartOfLambdaDefinition - This is called just before we start parsing the body of a lambda; it a...

void ActOnLambdaClosureParameters(Scope *LambdaScope, MutableArrayRef< DeclaratorChunk::ParamInfo > ParamInfo)

ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)

ActOnCXXBoolLiteral - Parse {true,false} literals.

bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)

ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenOrBraceLoc, MultiExprArg Exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization)

ActOnCXXTypeConstructExpr - Parse construction of a specified type.

ConditionResult ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK)

bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, SourceLocation ColonColonLoc, CXXScopeSpec &SS)

The parser has parsed a '__super' nested-name-specifier.

ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation ClosingBraceLoc)

StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)

ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, SourceLocation RParenLoc)

ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const,addrspace}_cast's.

ExprResult ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, SourceLocation EllipsisLoc, SourceLocation LSquareLoc, Expr *IndexExpr, SourceLocation RSquareLoc)

ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, ParsedType ObjectType)

ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer)

Parsed a C++ 'new' expression (C++ 5.3.4).

void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)

Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.

TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool AllowInjectedClassName=false)

Form a template name from a name that is syntactically required to name a template,...

ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)

SourceManager & getSourceManager() const

void ActOnLambdaExplicitTemplateParameterList(LambdaIntroducer &Intro, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > TParams, SourceLocation RAngleLoc, ExprResult RequiresClause)

This is called after parsing the explicit template parameter list on a lambda (if it exists) in C++2a...

bool ActOnCXXNestedNameSpecifierIndexedPack(CXXScopeSpec &SS, const DeclSpec &DS, SourceLocation ColonColonLoc, QualType Type)

ParsedType actOnLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init)

Perform initialization analysis of the init-capture and perform any implicit conversions such as an l...

void ActOnInitializerError(Decl *Dcl)

ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...

ExprResult ActOnNameClassifiedAsUndeclaredNonType(IdentifierInfo *Name, SourceLocation NameLoc)

Act on the result of classifying a name as an undeclared (ADL-only) non-type declaration.

TypeResult ActOnTypeName(Declarator &D)

void ActOnLambdaClosureQualifiers(LambdaIntroducer &Intro, SourceLocation MutableLoc)

void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, bool IsInstantiation=false)

ActOnLambdaError - If there is an error parsing a lambda, this callback is invoked to pop the informa...

concepts::Requirement * ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId)

ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)

Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.

ExprResult ActOnRequiresClause(ExprResult ConstraintExpr)

RequiresExprBodyDecl * ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, ArrayRef< ParmVarDecl * > LocalParameters, Scope *BodyScope)

@ PotentiallyEvaluated

The current expression is potentially evaluated at run time, which means that code may be generated t...

@ Unevaluated

The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...

void RecordParsingTemplateParameterDepth(unsigned Depth)

This is used to inform Sema what the current TemplateParameterDepth is during Parsing.

StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)

ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, Declarator &D, ParsedType &Ty, SourceLocation RParenLoc, Expr *CastExpr)

bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)

Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.

ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< ParsedType > Args, SourceLocation RParenLoc)

Parsed one of the type trait support pseudo-functions.

QualType ActOnPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc)

void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)

AddInitializerToDecl - Adds the initializer Init to the declaration dcl.

ParsedType getConstructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, bool EnteringContext)

ExprResult ActOnNameClassifiedAsDependentNonType(const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, bool IsAddressOfOperand)

Act on the result of classifying a name as an undeclared member of a dependent base class.

concepts::Requirement * ActOnNestedRequirement(Expr *Constraint)

static ConditionResult ConditionError()

bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, NestedNameSpecInfo &IdInfo, bool EnteringContext)

IsInvalidUnlessNestedName - This method is used for error recovery purposes to determine whether the ...

ExprResult ActOnCXXThis(SourceLocation Loc)

ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})

Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

void setBegin(SourceLocation b)

SourceLocation getEnd() const

SourceLocation getBegin() const

void setEnd(SourceLocation e)

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...

Represents a C++ template name within the type system.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

void setAnnotationEndLoc(SourceLocation L)

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

const char * getName() const

unsigned getLength() const

void setLength(unsigned Len)

void setKind(tok::TokenKind K)

SourceLocation getAnnotationEndLoc() const

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

void * getAnnotationValue() const

tok::TokenKind getKind() const

bool isRegularKeywordAttribute() const

Return true if the token is a keyword that is parsed in the same position as a standard attribute,...

void setEofData(const void *D)

SourceRange getAnnotationRange() const

SourceRange of the group of tokens that this annotation token represents.

void setLocation(SourceLocation L)

bool hasLeadingEmptyMacro() const

Return true if this token has an empty macro before it.

bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const

bool isNot(tok::TokenKind K) const

const void * getEofData() const

void startToken()

Reset all flags to cleared.

The base class of the type hierarchy.

QualType getCanonicalTypeInternal() const

Represents a C++ unqualified-id that has been parsed.

void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)

Specify that this unqualified-id was parsed as an identifier.

bool isValid() const

Determine whether this unqualified-id refers to a valid name.

void setTemplateId(TemplateIdAnnotation *TemplateId)

Specify that this unqualified-id was parsed as a template-id.

A static requirement that can be used in a requires-expression to check properties of types and expre...

uint32_t Literal

Literals are represented as positive integers.

@ After

Like System, but searched after the system directories.

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

The JSON file list parser is used to communicate input to InstallAPI.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

@ OO_None

Not an overloaded operator.

ArrayTypeTrait

Names for the array type traits.

LambdaCaptureKind

The different capture forms in a lambda introducer.

@ LCK_ByCopy

Capturing by copy (a.k.a., by value)

@ LCK_ByRef

Capturing by reference.

@ LCK_StarThis

Capturing the *this object by copy.

@ LCK_This

Capturing the *this object by reference.

@ IK_ConstructorName

A constructor name.

@ IK_LiteralOperatorId

A user-defined literal name, e.g., operator "" _i.

@ IK_Identifier

An identifier.

@ IK_DestructorName

A destructor name.

@ IK_OperatorFunctionId

An overloaded operator name, e.g., operator+.

@ CopyInit

[a = b], [a = {b}]

@ Result

The result type of a method or function.

ActionResult< Expr * > ExprResult

TemplateNameKind

Specifies the kind of template name that an identifier refers to.

@ TNK_Var_template

The name refers to a variable template whose specialization produces a variable.

@ TNK_Dependent_template_name

The name refers to a dependent template name:

@ TNK_Function_template

The name refers to a function template or a set of overloaded functions that includes at least one fu...

@ TNK_Non_template

The name does not refer to a template.

@ TNK_Undeclared_template

Lookup for the name failed, but we're assuming it was a template name anyway.

const FunctionProtoType * T

const char * getOperatorSpelling(OverloadedOperatorKind Operator)

Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.

TypeTrait

Names for traits that operate specifically on types.

@ Parens

New-expression has a C++98 paren-delimited initializer.

@ Braces

New-expression has a C++11 list-initializer.

ExceptionSpecificationType

The various types of exception specifications that exist in C++11.

@ EST_None

no exception specification

static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)

DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.

static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)

Return a DeclaratorChunk for an array.

Represents a complete lambda introducer.

bool hasLambdaCapture() const

void addCapture(LambdaCaptureKind Kind, SourceLocation Loc, IdentifierInfo *Id, SourceLocation EllipsisLoc, LambdaCaptureInitKind InitKind, ExprResult Init, ParsedType InitCaptureType, SourceRange ExplicitRange)

Append a capture in a lambda introducer.

SourceLocation DefaultLoc

LambdaCaptureDefault Default

Describes how types, statements, expressions, and declarations should be printed.

Keeps information about an identifier in a nested-name-spec.

Information about a template-id annotation token.

const IdentifierInfo * Name

FIXME: Temporarily stores the name of a specialization.

unsigned NumArgs

NumArgs - The number of template arguments.

SourceLocation TemplateNameLoc

TemplateNameLoc - The location of the template name within the source.

ParsedTemplateArgument * getTemplateArgs()

Retrieves a pointer to the template arguments.

SourceLocation RAngleLoc

The location of the '>' after the template argument list.

SourceLocation LAngleLoc

The location of the '<' before the template argument list.

SourceLocation TemplateKWLoc

TemplateKWLoc - The location of the template keyword.

ParsedTemplateTy Template

The declaration of the template corresponding to the template-name.

static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef< ParsedTemplateArgument > TemplateArgs, bool ArgsInvalid, SmallVectorImpl< TemplateIdAnnotation * > &CleanupList)

Creates a new TemplateIdAnnotation with NumArgs arguments and appends it to List.