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

1

2

3

4

5

6

7

8

9

10

11

12

13

30#include "llvm/ADT/STLExtras.h"

31#include

32

33using namespace clang;

34

35

36

37

38

39

40

42 ParsedStmtContext StmtCtx) {

44

45

46

48 do {

49 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);

51

52 return Res;

53}

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

105Parser::ParseStatementOrDeclaration(StmtVector &Stmts,

106 ParsedStmtContext StmtCtx,

108

110

111

112

113

114

115

117 MaybeParseCXX11Attributes(CXX11Attrs, true);

120 MaybeParseGNUAttributes(GNUOrMSAttrs);

121

123 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);

124

125 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(

126 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs);

127 MaybeDestroyTemplateIds();

128

129

130

133

135 "attributes on empty statement");

136

137 if (Attrs.empty() || Res.isInvalid())

138 return Res;

139

141}

142

143namespace {

145public:

146 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {

147 WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,

148 tok::identifier, tok::star, tok::amp);

149 WantExpressionKeywords =

150 nextTok.isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);

151 WantRemainingKeywords =

152 nextTok.isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);

153 WantCXXNamedCasts = false;

154 }

155

156 bool ValidateCandidate(const TypoCorrection &candidate) override {

159 if (NextToken.is(tok::equal))

161 if (NextToken.is(tok::period) &&

163 return false;

165 }

166

167 std::unique_ptr clone() override {

168 return std::make_unique(*this);

169 }

170

171private:

173};

174}

175

176StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(

177 StmtVector &Stmts, ParsedStmtContext StmtCtx,

180 const char *SemiError = nullptr;

183

184

185

186

187Retry:

190 switch (Kind) {

191 case tok::at:

192 {

194 return ParseObjCAtStatement(AtLoc, StmtCtx);

195 }

196

197 case tok::code_completion:

198 cutOffParsing();

202

203 case tok::identifier:

204 ParseIdentifier: {

206 if (Next.is(tok::colon)) {

207

208

209

212

213

214 return ParseLabeledStatement(Attrs, StmtCtx);

215 }

216

217

218

219 if (Next.isNot(tok::coloncolon)) {

220

221

222 StatementFilterCCC CCC(Next);

223 if (TryAnnotateName(&CCC) == ANK_Error) {

224

225

227 if (Tok.is(tok::semi))

230 }

231

232

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

234 goto Retry;

235 }

236

237

238 [[fallthrough]];

239 }

240

241 default: {

242 bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty();

243 auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); };

244 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&

245 llvm::all_of(GNUAttrs, IsStmtAttr);

246

247

248

249

250

252 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=

253 ParsedStmtContext()) &&

254 ((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||

255 isDeclarationStatement())) {

258 if (GNUAttributeLoc.isValid()) {

259 DeclStart = GNUAttributeLoc;

261 GNUAttrs, &GNUAttributeLoc);

262 } else {

264 GNUAttrs);

265 }

267

268

275 }

276

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

278 Diag(Tok, diag::err_expected_statement);

280 }

281

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

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

286 Tok.setKind(tok::identifier);

287 Diag(Tok, diag::ext_keyword_as_ident)

289 goto ParseIdentifier;

290 }

291 [[fallthrough]];

292 default:

293 return ParseExprStatement(StmtCtx);

294 }

295 }

296

297 case tok::kw___attribute: {

299 ParseGNUAttributes(GNUAttrs);

300 goto Retry;

301 }

302

303 case tok::kw_template: {

307 Attrs,

308 getAccessSpecifierIfPresent());

310 }

311

312 case tok::kw_case:

313 return ParseCaseStatement(StmtCtx);

314 case tok::kw_default:

315 return ParseDefaultStatement(StmtCtx);

316

317 case tok::l_brace:

318 return ParseCompoundStatement();

319 case tok:🚛 {

322 }

323

324 case tok::kw_if:

325 return ParseIfStatement(TrailingElseLoc);

326 case tok::kw_switch:

327 return ParseSwitchStatement(TrailingElseLoc);

328

329 case tok::kw_while:

330 return ParseWhileStatement(TrailingElseLoc);

331 case tok::kw_do:

332 Res = ParseDoStatement();

333 SemiError = "do/while";

334 break;

335 case tok::kw_for:

336 return ParseForStatement(TrailingElseLoc);

337

338 case tok::kw_goto:

339 Res = ParseGotoStatement();

340 SemiError = "goto";

341 break;

342 case tok::kw_continue:

343 Res = ParseContinueStatement();

344 SemiError = "continue";

345 break;

346 case tok::kw_break:

347 Res = ParseBreakStatement();

348 SemiError = "break";

349 break;

350 case tok::kw_return:

351 Res = ParseReturnStatement();

352 SemiError = "return";

353 break;

354 case tok::kw_co_return:

355 Res = ParseReturnStatement();

356 SemiError = "co_return";

357 break;

358

359 case tok::kw_asm: {

360 for (const ParsedAttr &AL : CXX11Attrs)

361

362

363 (AL.isRegularKeywordAttribute()

364 ? Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)

365 : Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))

366 << AL;

367

368 CXX11Attrs.clear();

369 ProhibitAttributes(GNUAttrs);

370 bool msAsm = false;

371 Res = ParseAsmStatement(msAsm);

372 if (msAsm) return Res;

373 SemiError = "asm";

374 break;

375 }

376

377 case tok::kw___if_exists:

378 case tok::kw___if_not_exists:

379 ProhibitAttributes(CXX11Attrs);

380 ProhibitAttributes(GNUAttrs);

381 ParseMicrosoftIfExistsStatement(Stmts);

382

383

385

386 case tok::kw_try:

387 return ParseCXXTryBlock();

388

389 case tok::kw___try:

390 ProhibitAttributes(CXX11Attrs);

391 ProhibitAttributes(GNUAttrs);

392 return ParseSEHTryBlock();

393

394 case tok::kw___leave:

395 Res = ParseSEHLeaveStatement();

396 SemiError = "__leave";

397 break;

398

399 case tok::annot_pragma_vis:

400 ProhibitAttributes(CXX11Attrs);

401 ProhibitAttributes(GNUAttrs);

402 HandlePragmaVisibility();

404

405 case tok::annot_pragma_pack:

406 ProhibitAttributes(CXX11Attrs);

407 ProhibitAttributes(GNUAttrs);

408 HandlePragmaPack();

410

411 case tok::annot_pragma_msstruct:

412 ProhibitAttributes(CXX11Attrs);

413 ProhibitAttributes(GNUAttrs);

414 HandlePragmaMSStruct();

416

417 case tok::annot_pragma_align:

418 ProhibitAttributes(CXX11Attrs);

419 ProhibitAttributes(GNUAttrs);

420 HandlePragmaAlign();

422

423 case tok::annot_pragma_weak:

424 ProhibitAttributes(CXX11Attrs);

425 ProhibitAttributes(GNUAttrs);

426 HandlePragmaWeak();

428

429 case tok::annot_pragma_weakalias:

430 ProhibitAttributes(CXX11Attrs);

431 ProhibitAttributes(GNUAttrs);

432 HandlePragmaWeakAlias();

434

435 case tok::annot_pragma_redefine_extname:

436 ProhibitAttributes(CXX11Attrs);

437 ProhibitAttributes(GNUAttrs);

438 HandlePragmaRedefineExtname();

440

441 case tok::annot_pragma_fp_contract:

442 ProhibitAttributes(CXX11Attrs);

443 ProhibitAttributes(GNUAttrs);

444 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";

445 ConsumeAnnotationToken();

447

448 case tok::annot_pragma_fp:

449 ProhibitAttributes(CXX11Attrs);

450 ProhibitAttributes(GNUAttrs);

451 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";

452 ConsumeAnnotationToken();

454

455 case tok::annot_pragma_fenv_access:

456 case tok::annot_pragma_fenv_access_ms:

457 ProhibitAttributes(CXX11Attrs);

458 ProhibitAttributes(GNUAttrs);

459 Diag(Tok, diag::err_pragma_file_or_compound_scope)

460 << (Kind == tok::annot_pragma_fenv_access ? "STDC FENV_ACCESS"

461 : "fenv_access");

462 ConsumeAnnotationToken();

464

465 case tok::annot_pragma_fenv_round:

466 ProhibitAttributes(CXX11Attrs);

467 ProhibitAttributes(GNUAttrs);

468 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND";

469 ConsumeAnnotationToken();

471

472 case tok::annot_pragma_cx_limited_range:

473 ProhibitAttributes(CXX11Attrs);

474 ProhibitAttributes(GNUAttrs);

475 Diag(Tok, diag::err_pragma_file_or_compound_scope)

476 << "STDC CX_LIMITED_RANGE";

477 ConsumeAnnotationToken();

479

480 case tok::annot_pragma_float_control:

481 ProhibitAttributes(CXX11Attrs);

482 ProhibitAttributes(GNUAttrs);

483 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";

484 ConsumeAnnotationToken();

486

487 case tok::annot_pragma_opencl_extension:

488 ProhibitAttributes(CXX11Attrs);

489 ProhibitAttributes(GNUAttrs);

490 HandlePragmaOpenCLExtension();

492

493 case tok::annot_pragma_captured:

494 ProhibitAttributes(CXX11Attrs);

495 ProhibitAttributes(GNUAttrs);

496 return HandlePragmaCaptured();

497

498 case tok::annot_pragma_openmp:

499

500

501 ProhibitAttributes(CXX11Attrs);

502 ProhibitAttributes(GNUAttrs);

503 [[fallthrough]];

504 case tok::annot_attr_openmp:

505

506 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);

507

508 case tok::annot_pragma_openacc:

510

511 case tok::annot_pragma_ms_pointers_to_members:

512 ProhibitAttributes(CXX11Attrs);

513 ProhibitAttributes(GNUAttrs);

514 HandlePragmaMSPointersToMembers();

516

517 case tok::annot_pragma_ms_pragma:

518 ProhibitAttributes(CXX11Attrs);

519 ProhibitAttributes(GNUAttrs);

520 HandlePragmaMSPragma();

522

523 case tok::annot_pragma_ms_vtordisp:

524 ProhibitAttributes(CXX11Attrs);

525 ProhibitAttributes(GNUAttrs);

526 HandlePragmaMSVtorDisp();

528

529 case tok::annot_pragma_loop_hint:

530 ProhibitAttributes(CXX11Attrs);

531 ProhibitAttributes(GNUAttrs);

532 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);

533

534 case tok::annot_pragma_dump:

535 HandlePragmaDump();

537

538 case tok::annot_pragma_attribute:

539 HandlePragmaAttribute();

541 }

542

543

545

546

547

548 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);

549

551 }

552

553 return Res;

554}

555

556

557StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {

558

559 Token OldToken = Tok;

560

562

563

565 if (Expr.isInvalid()) {

566

567

568

570 if (Tok.is(tok::semi))

573 }

574

575 if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&

577

578

579 Diag(OldToken, diag::err_expected_case_before_expression)

581

582

583 return ParseCaseStatement(StmtCtx, true, Expr);

584 }

585

586 Token *CurTok = nullptr;

587

588 if (Tok.is(tok::annot_repl_input_end))

589 CurTok = &Tok;

590 else

591

592 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);

593

597

598 return R;

599}

600

601

602

603

604

605

606

607

608

609

610StmtResult Parser::ParseSEHTryBlock() {

611 assert(Tok.is(tok::kw___try) && "Expected '__try'");

613

614 if (Tok.isNot(tok::l_brace))

615 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);

616

617 StmtResult TryBlock(ParseCompoundStatement(

618 false,

620 if (TryBlock.isInvalid())

621 return TryBlock;

622

624 if (Tok.is(tok::identifier) &&

627 Handler = ParseSEHExceptBlock(Loc);

628 } else if (Tok.is(tok::kw___finally)) {

630 Handler = ParseSEHFinallyBlock(Loc);

631 } else {

632 return StmtError(Diag(Tok, diag::err_seh_expected_handler));

633 }

634

636 return Handler;

637

639 TryLoc,

640 TryBlock.get(),

641 Handler.get());

642}

643

644

645

646

647

648

651 raii2(Ident___exception_code, false),

652 raii3(Ident_GetExceptionCode, false);

653

654 if (ExpectAndConsume(tok::l_paren))

656

659

664 }

665

667 {

668 ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |

671 }

672

677 }

678

681

682 if (ExpectAndConsume(tok::r_paren))

684

685 if (Tok.isNot(tok::l_brace))

686 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);

687

689

690 if(Block.isInvalid())

692

694}

695

696

697

698

699

700

703 raii2(Ident___abnormal_termination, false),

704 raii3(Ident_AbnormalTermination, false);

705

706 if (Tok.isNot(tok::l_brace))

707 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);

708

709 ParseScope FinallyScope(this, 0);

711

713 if(Block.isInvalid()) {

716 }

717

719}

720

721

722

723

724

725

726StmtResult Parser::ParseSEHLeaveStatement() {

729}

730

732

733

734 if (P.getLangOpts().CPlusPlus && P.getLangOpts().MicrosoftExt &&

735 isa(SubStmt)) {

737 P.getLangOpts().C23

738 ? diag::warn_c23_compat_label_followed_by_declaration

739 : diag::ext_c_label_followed_by_declaration);

740 }

741}

742

743

744

745

746

747

748

749

750

751

753 ParsedStmtContext StmtCtx) {

755 "Not an identifier!");

756

757

758

759

760 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;

761

762 Token IdentTok = Tok;

764

765 assert(Tok.is(tok::colon) && "Not a label!");

766

767

769

770

772 if (Tok.is(tok::kw___attribute)) {

774 ParseGNUAttributes(TempAttrs);

775

776

777

778

779

780

781

782

785 else {

788 SubStmt = ParseStatementOrDeclarationAfterAttributes(

789 Stmts, StmtCtx, nullptr, EmptyCXX11Attrs, TempAttrs);

790 if (!TempAttrs.empty() && !SubStmt.isInvalid())

792 }

793 }

794

795

796 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {

797 DiagnoseLabelAtEndOfCompoundStatement();

799 }

800

801

803 SubStmt = ParseStatement(nullptr, StmtCtx);

804

805

808

810

815

817 SubStmt.get());

818}

819

820

821

822

823

824

825StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,

827 assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");

828

829

830

831

832 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849

851

852

853

854

855 Stmt *DeepestParsedCaseStmt = nullptr;

856

857

859 do {

863

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

865 cutOffParsing();

868 }

869

870

871

872

874

876 if (!MissingCase) {

879

880

883 }

884 } else {

886 MissingCase = false;

887 }

888

889

893

894 unsigned DiagId;

896 DiagId = diag::ext_gnu_case_range;

898 DiagId = diag::warn_c23_compat_case_range;

899 else

900 DiagId = diag::ext_c2y_case_range;

901 Diag(DotDotDotLoc, DiagId);

906 }

907 }

908

909 ColonProtection.restore();

910

914

915 Diag(ColonLoc, diag::err_expected_after)

916 << "'case'" << tok::colon

918 } else {

920 Diag(ExpectedLoc, diag::err_expected_after)

921 << "'case'" << tok::colon

923 ColonLoc = ExpectedLoc;

924 }

925

927 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);

928

929

930

932 if (TopLevelCase.isInvalid())

933 return ParseStatement(nullptr, StmtCtx);

934

935 } else {

936

937

938 Stmt *NextDeepest = Case.get();

939 if (TopLevelCase.isInvalid())

940 TopLevelCase = Case;

941 else

943 DeepestParsedCaseStmt = NextDeepest;

944 }

945

946

947 } while (Tok.is(tok::kw_case));

948

949

951

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

953

954

955 DiagnoseLabelAtEndOfCompoundStatement();

957 } else {

958 SubStmt = ParseStatement(nullptr, StmtCtx);

959 }

960

961

962 if (DeepestParsedCaseStmt) {

963

968 }

969

970

971 return TopLevelCase;

972}

973

974

975

976

977

978

979StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {

980 assert(Tok.is(tok::kw_default) && "Not a default stmt!");

981

982

983

984

985 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;

986

988

992

993 Diag(ColonLoc, diag::err_expected_after)

994 << "'default'" << tok::colon

996 } else {

998 Diag(ExpectedLoc, diag::err_expected_after)

999 << "'default'" << tok::colon

1001 ColonLoc = ExpectedLoc;

1002 }

1003

1005

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

1007

1008

1009 DiagnoseLabelAtEndOfCompoundStatement();

1011 } else {

1012 SubStmt = ParseStatement(nullptr, StmtCtx);

1013 }

1014

1015

1018

1022}

1023

1024StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {

1025 return ParseCompoundStatement(isStmtExpr,

1027}

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,

1052 unsigned ScopeFlags) {

1053 assert(Tok.is(tok::l_brace) && "Not a compound stmt!");

1054

1055

1056

1057 ParseScope CompoundScope(this, ScopeFlags);

1058

1059

1060 return ParseCompoundStatementBody(isStmtExpr);

1061}

1062

1063

1064

1065

1066void Parser::ParseCompoundStatementLeadingPragmas() {

1067 bool checkForPragmas = true;

1068 while (checkForPragmas) {

1069 switch (Tok.getKind()) {

1070 case tok::annot_pragma_vis:

1071 HandlePragmaVisibility();

1072 break;

1073 case tok::annot_pragma_pack:

1074 HandlePragmaPack();

1075 break;

1076 case tok::annot_pragma_msstruct:

1077 HandlePragmaMSStruct();

1078 break;

1079 case tok::annot_pragma_align:

1080 HandlePragmaAlign();

1081 break;

1082 case tok::annot_pragma_weak:

1083 HandlePragmaWeak();

1084 break;

1085 case tok::annot_pragma_weakalias:

1086 HandlePragmaWeakAlias();

1087 break;

1088 case tok::annot_pragma_redefine_extname:

1089 HandlePragmaRedefineExtname();

1090 break;

1091 case tok::annot_pragma_opencl_extension:

1092 HandlePragmaOpenCLExtension();

1093 break;

1094 case tok::annot_pragma_fp_contract:

1095 HandlePragmaFPContract();

1096 break;

1097 case tok::annot_pragma_fp:

1098 HandlePragmaFP();

1099 break;

1100 case tok::annot_pragma_fenv_access:

1101 case tok::annot_pragma_fenv_access_ms:

1102 HandlePragmaFEnvAccess();

1103 break;

1104 case tok::annot_pragma_fenv_round:

1105 HandlePragmaFEnvRound();

1106 break;

1107 case tok::annot_pragma_cx_limited_range:

1108 HandlePragmaCXLimitedRange();

1109 break;

1110 case tok::annot_pragma_float_control:

1111 HandlePragmaFloatControl();

1112 break;

1113 case tok::annot_pragma_ms_pointers_to_members:

1114 HandlePragmaMSPointersToMembers();

1115 break;

1116 case tok::annot_pragma_ms_pragma:

1117 HandlePragmaMSPragma();

1118 break;

1119 case tok::annot_pragma_ms_vtordisp:

1120 HandlePragmaMSVtorDisp();

1121 break;

1122 case tok::annot_pragma_dump:

1123 HandlePragmaDump();

1124 break;

1125 default:

1126 checkForPragmas = false;

1127 break;

1128 }

1129 }

1130

1131}

1132

1133void Parser::DiagnoseLabelAtEndOfCompoundStatement() {

1136 ? diag::warn_cxx20_compat_label_end_of_compound_statement

1137 : diag::ext_cxx_label_end_of_compound_statement);

1138 } else {

1140 ? diag::warn_c23_compat_label_end_of_compound_statement

1141 : diag::ext_c_label_end_of_compound_statement);

1142 }

1143}

1144

1145

1146

1147bool Parser::ConsumeNullStmt(StmtVector &Stmts) {

1148 if (!Tok.is(tok::semi))

1149 return false;

1150

1153

1157

1158

1160 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);

1162 Stmts.push_back(R.get());

1163 }

1164

1165

1167 return false;

1168

1169 Diag(StartLoc, diag::warn_null_statement)

1171 return true;

1172}

1173

1175 bool IsStmtExprResult = false;

1176 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {

1177

1178 unsigned LookAhead = 0;

1179 while (GetLookAheadToken(LookAhead).is(tok::semi)) {

1180 ++LookAhead;

1181 }

1182

1183

1184

1185 IsStmtExprResult = GetLookAheadToken(LookAhead).is(tok::r_brace) &&

1186 GetLookAheadToken(LookAhead + 1).is(tok::r_paren);

1187 }

1188

1189 if (IsStmtExprResult)

1191 return Actions.ActOnExprStmt(E, !IsStmtExprResult);

1192}

1193

1194

1195

1196

1197

1198StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {

1201 "in compound statement ('{}')");

1202

1203

1204

1206

1209 if (T.consumeOpen())

1211

1213

1214

1215 ParseCompoundStatementLeadingPragmas();

1217

1219

1220

1221

1222 while (Tok.is(tok::kw___label__)) {

1224

1226 while (true) {

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

1228 Diag(Tok, diag::err_expected) << tok::identifier;

1229 break;

1230 }

1231

1234 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));

1235

1237 break;

1238 }

1239

1244

1245 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);

1247 Stmts.push_back(R.get());

1248 }

1249

1250 ParsedStmtContext SubStmtCtx =

1251 ParsedStmtContext::Compound |

1252 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());

1253

1254 bool LastIsError = false;

1255 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&

1256 Tok.isNot(tok::eof)) {

1257 if (Tok.is(tok::annot_pragma_unused)) {

1258 HandlePragmaUnused();

1259 continue;

1260 }

1261

1262 if (ConsumeNullStmt(Stmts))

1263 continue;

1264

1266 if (Tok.isNot(tok::kw___extension__)) {

1267 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);

1268 } else {

1269

1270

1271

1272

1274 while (Tok.is(tok::kw___extension__))

1276

1278 MaybeParseCXX11Attributes(attrs, true);

1279

1280

1281 if (isDeclarationStatement()) {

1282

1283

1285

1289 attrs, DeclSpecAttrs);

1290 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);

1291 } else {

1292

1293 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));

1294

1295 if (Res.isInvalid()) {

1297 continue;

1298 }

1299

1300

1301

1302 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);

1303 R = handleExprStmt(Res, SubStmtCtx);

1306 }

1307 }

1308

1310 Stmts.push_back(R.get());

1312 }

1313

1314

1315

1316

1317 if (isStmtExpr && LastIsError && !Stmts.empty())

1319

1320

1321

1322

1323

1329 diag::warn_no_support_for_eval_method_source_on_m32);

1330

1332

1333

1334 if (T.consumeClose()) {

1335

1336

1337 if (isStmtExpr && Tok.is(tok::r_paren))

1338 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);

1339 } else {

1340

1341

1342 }

1343

1344 if (T.getCloseLocation().isValid())

1345 CloseLoc = T.getCloseLocation();

1346

1348 Stmts, isStmtExpr);

1349}

1350

1351

1352

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363

1364

1365bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,

1372 T.consumeOpen();

1374

1376 Cond = ParseCXXCondition(InitStmt, Loc, CK, false);

1377 } else {

1379

1380

1383 else

1385 false);

1386 }

1387

1388

1389

1390

1393

1394

1395 if (Tok.isNot(tok::r_paren))

1396 return true;

1397 }

1398

1401 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},

1405 false);

1406 }

1407

1408

1409 T.consumeClose();

1410 LParenLoc = T.getOpenLocation();

1411 RParenLoc = T.getCloseLocation();

1412

1413

1414

1415

1416 while (Tok.is(tok::r_paren)) {

1417 Diag(Tok, diag::err_extraneous_rparen_in_condition)

1419 ConsumeParen();

1420 }

1421

1422 return false;

1423}

1424

1425namespace {

1426

1427enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };

1428

1429struct MisleadingIndentationChecker {

1433 unsigned NumDirectives;

1434 MisleadingStatementKind Kind;

1435 bool ShouldSkip;

1436 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,

1438 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),

1439 NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),

1440 ShouldSkip(P.getCurToken().is(tok::l_brace)) {

1441 if (P.MisleadingIndentationElseLoc.isInvalid()) {

1442 StmtLoc = P.MisleadingIndentationElseLoc;

1444 }

1445 if (Kind == MSK_else && !ShouldSkip)

1446 P.MisleadingIndentationElseLoc = SL;

1447 }

1448

1449

1450

1452 unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;

1453

1454 unsigned ColNo = SM.getSpellingColumnNumber(Loc);

1455 if (ColNo == 0 || TabStop == 1)

1456 return ColNo;

1457

1458 std::pair<FileID, unsigned> FIDAndOffset = SM.getDecomposedLoc(Loc);

1459

1461 StringRef BufData = SM.getBufferData(FIDAndOffset.first, &Invalid);

1463 return 0;

1464

1465 const char *EndPos = BufData.data() + FIDAndOffset.second;

1466

1467 assert(FIDAndOffset.second + 1 >= ColNo &&

1468 "Column number smaller than file offset?");

1469

1470 unsigned VisualColumn = 0;

1471

1472

1473 for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;

1474 ++CurPos) {

1475 if (*CurPos == '\t')

1476

1477 VisualColumn += (TabStop - VisualColumn % TabStop);

1478 else

1479 VisualColumn++;

1480 }

1481 return VisualColumn + 1;

1482 }

1483

1484 void Check() {

1485 Token Tok = P.getCurToken();

1486 if (P.getActions().getDiagnostics().isIgnored(

1487 diag::warn_misleading_indentation, Tok.getLocation()) ||

1488 ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||

1492 (Kind == MSK_else && P.MisleadingIndentationElseLoc.isInvalid())) {

1494 return;

1495 }

1496 if (Kind == MSK_else)

1498

1500 unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);

1501 unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());

1502 unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);

1503

1504 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&

1505 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||

1507 SM.getPresumedLineNumber(StmtLoc) !=

1509 (Tok.isNot(tok::identifier) ||

1510 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {

1511 P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;

1512 P.Diag(StmtLoc, diag::note_previous_statement);

1513 }

1514 }

1515};

1516

1517}

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1529 assert(Tok.is(tok::kw_if) && "Not an if stmt!");

1531

1532 bool IsConstexpr = false;

1533 bool IsConsteval = false;

1536

1537 if (Tok.is(tok::kw_constexpr)) {

1538

1541 : diag::ext_constexpr_if);

1542 IsConstexpr = true;

1544 }

1545 } else {

1546 if (Tok.is(tok::exclaim)) {

1548 }

1549

1550 if (Tok.is(tok::kw_consteval)) {

1552 : diag::ext_consteval_if);

1553 IsConsteval = true;

1555 }

1556 }

1557 if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {

1558 Diag(Tok, diag::err_expected_lparen_after) << "if";

1561 }

1562

1564

1565

1566

1567

1568

1569

1570

1571

1572

1573

1574

1575

1576

1578

1579

1584 std::optional ConstexprCondition;

1585 if (!IsConsteval) {

1586

1587 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,

1590 LParen, RParen))

1592

1593 if (IsConstexpr)

1595 }

1596

1597 bool IsBracedThen = Tok.is(tok::l_brace);

1598

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1609

1610

1611

1612

1613

1614

1615

1616

1617 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);

1618

1619 MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);

1620

1621

1623

1626 {

1627 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;

1630 if (NotLocation.isInvalid() && IsConsteval) {

1632 ShouldEnter = true;

1633 }

1634

1636 Actions, Context, nullptr,

1638 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);

1639 }

1640

1641 if (Tok.isNot(tok::kw_else))

1642 MIChecker.Check();

1643

1644

1645 InnerScope.Exit();

1646

1647

1651

1652 if (Tok.is(tok::kw_else)) {

1653 if (TrailingElseLoc)

1655

1658

1659

1660

1661

1662

1663

1664

1665

1666

1667

1669 Tok.is(tok::l_brace));

1670

1671 MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);

1672 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;

1675 if (NotLocation.isValid() && IsConsteval) {

1677 ShouldEnter = true;

1678 }

1679

1681 Actions, Context, nullptr,

1683 ElseStmt = ParseStatement();

1684

1686 MIChecker.Check();

1687

1688

1689 InnerScope.Exit();

1690 } else if (Tok.is(tok::code_completion)) {

1691 cutOffParsing();

1694 } else if (InnerStatementTrailingElseLoc.isValid()) {

1695 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);

1696 }

1697

1698 IfScope.Exit();

1699

1700

1701

1702

1704 (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||

1705 (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {

1706

1708 }

1709

1710 if (IsConsteval) {

1711 auto IsCompoundStatement = [](const Stmt *S) {

1712 if (const auto *Outer = dyn_cast_if_present(S))

1713 S = Outer->getSubStmt();

1714 return isa_and_nonnullclang::CompoundStmt(S);

1715 };

1716

1717 if (!IsCompoundStatement(ThenStmt.get())) {

1718 Diag(ConstevalLoc, diag::err_expected_after) << "consteval"

1719 << "{";

1721 }

1722 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {

1723 Diag(ElseLoc, diag::err_expected_after) << "else"

1724 << "{";

1726 }

1727 }

1728

1729

1734

1736 if (IsConstexpr)

1738 else if (IsConsteval)

1741

1742 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(), Cond, RParen,

1743 ThenStmt.get(), ElseLoc, ElseStmt.get());

1744}

1745

1746

1747

1748

1749

1751 assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");

1753

1754 if (Tok.isNot(tok::l_paren)) {

1755 Diag(Tok, diag::err_expected_lparen_after) << "switch";

1758 }

1759

1761

1762

1763

1764

1765

1766

1767

1768

1769

1770

1771

1772

1773

1775 if (C99orCXX)

1777 ParseScope SwitchScope(this, ScopeFlags);

1778

1779

1784 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,

1787

1789 SwitchLoc, LParen, InitStmt.get(), Cond, RParen);

1790

1791 if (Switch.isInvalid()) {

1792

1793

1794

1795

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

1797 ConsumeBrace();

1799 } else

1802 }

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1816 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));

1817

1818

1819

1820 if (C99orCXX)

1822

1823

1824 StmtResult Body(ParseStatement(TrailingElseLoc));

1825

1826

1827 InnerScope.Exit();

1828 SwitchScope.Exit();

1829

1831}

1832

1833

1834

1835

1836

1838 assert(Tok.is(tok::kw_while) && "Not a while stmt!");

1841

1842 if (Tok.isNot(tok::l_paren)) {

1843 Diag(Tok, diag::err_expected_lparen_after) << "while";

1846 }

1847

1849

1850

1851

1852

1853

1854

1855

1856

1857

1858

1859

1860

1861

1862 unsigned ScopeFlags;

1863 if (C99orCXX)

1866 else

1868 ParseScope WhileScope(this, ScopeFlags);

1869

1870

1874 if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,

1877

1878

1879

1882

1883

1884

1885

1886

1887

1888

1889

1890

1891

1892

1893

1894 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));

1895

1896 MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);

1897

1898

1899 StmtResult Body(ParseStatement(TrailingElseLoc));

1900

1901 if (Body.isUsable())

1902 MIChecker.Check();

1903

1904 InnerScope.Exit();

1905 WhileScope.Exit();

1906

1907 if (Cond.isInvalid() || Body.isInvalid())

1909

1910 return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());

1911}

1912

1913

1914

1915

1916

1917StmtResult Parser::ParseDoStatement() {

1918 assert(Tok.is(tok::kw_do) && "Not a do stmt!");

1920

1921

1922

1923 unsigned ScopeFlags;

1926 else

1928

1929 ParseScope DoScope(this, ScopeFlags);

1930

1931

1932

1935

1936

1937

1938

1939

1940

1941

1942

1943

1945 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));

1946

1947

1949

1950

1951 InnerScope.Exit();

1952

1953 if (Tok.isNot(tok::kw_while)) {

1954 if (!Body.isInvalid()) {

1955 Diag(Tok, diag::err_expected_while);

1956 Diag(DoLoc, diag::note_matching) << "'do'";

1958 }

1960 }

1962

1963 if (Tok.isNot(tok::l_paren)) {

1964 Diag(Tok, diag::err_expected_lparen_after) << "do/while";

1967 }

1968

1969

1971 T.consumeOpen();

1972

1973

1974 DiagnoseAndSkipCXX11Attributes();

1975

1978

1981 true);

1982 else {

1983 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))

1986 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},

1988 }

1989 T.consumeClose();

1990 DoScope.Exit();

1991

1992 if (Cond.isInvalid() || Body.isInvalid())

1994

1995 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),

1996 Cond.get(), T.getCloseLocation());

1997}

1998

1999bool Parser::isForRangeIdentifier() {

2000 assert(Tok.is(tok::identifier));

2001

2003 if (Next.is(tok::colon))

2004 return true;

2005

2006 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {

2007 TentativeParsingAction PA(*this);

2009 SkipCXX11Attributes();

2010 bool Result = Tok.is(tok::colon);

2011 PA.Revert();

2013 }

2014

2015 return false;

2016}

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

2027

2028

2029

2030

2031

2032

2033

2034

2035

2036

2037

2038

2039

2040

2042 assert(Tok.is(tok::kw_for) && "Not a for stmt!");

2044

2046 if (Tok.is(tok::kw_co_await))

2048

2049 if (Tok.isNot(tok::l_paren)) {

2050 Diag(Tok, diag::err_expected_lparen_after) << "for";

2053 }

2054

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067

2068

2069

2070

2071

2072

2073 unsigned ScopeFlags = 0;

2074 if (C99orCXXorObjC)

2076

2077 ParseScope ForScope(this, ScopeFlags);

2078

2080 T.consumeOpen();

2081

2083

2084 bool ForEach = false;

2088 ForRangeInfo ForRangeInfo;

2090

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

2092 cutOffParsing();

2097 }

2098

2100 MaybeParseCXX11Attributes(attrs);

2101

2103

2104

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

2106 ProhibitAttributes(attrs);

2107

2110 EmptyInitStmtSemiLoc = SemiLoc;

2113 isForRangeIdentifier()) {

2114 ProhibitAttributes(attrs);

2117 MaybeParseCXX11Attributes(attrs);

2118

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

2121 ForRangeInfo.RangeExpr = ParseBraceInitializer();

2122 else

2124

2125 Diag(Loc, diag::err_for_range_identifier)

2129

2130 ForRangeInfo.LoopVar =

2132 } else if (isForInitDeclaration()) {

2134

2135

2136 if (!C99orCXXorObjC) {

2137 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);

2138 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);

2139 }

2142 if (Tok.is(tok::kw_using)) {

2144 attrs);

2146 } else {

2147

2148 bool MightBeForRangeStmt = getLangOpts().CPlusPlus;

2151 DG = ParseSimpleDeclaration(

2153 MightBeForRangeStmt ? &ForRangeInfo : nullptr);

2155 if (ForRangeInfo.ParsedForRangeDecl()) {

2157 ? diag::warn_cxx98_compat_for_range

2158 : diag::ext_for_range);

2159 ForRangeInfo.LoopVar = FirstPart;

2161 } else if (Tok.is(tok::semi)) {

2163 } else if ((ForEach = isTokIdentifier_in())) {

2165

2167

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

2169 cutOffParsing();

2171 DG);

2173 }

2175 } else {

2176 Diag(Tok, diag::err_expected_semi_for);

2177 }

2178 }

2179 } else {

2180 ProhibitAttributes(attrs);

2182

2183 ForEach = isTokIdentifier_in();

2184

2185

2186 if (Value.isInvalid()) {

2187 if (ForEach)

2189 else {

2190

2191

2192

2193

2194

2195 bool IsRangeBasedFor =

2196 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);

2198 }

2199 }

2200

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

2203 } else if (ForEach) {

2205

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

2207 cutOffParsing();

2209 nullptr);

2211 }

2214

2215

2216 Diag(Tok, diag::err_for_range_expected_decl)

2220 } else {

2221 if (Value.isInvalid()) {

2222 Diag(Tok, diag::err_expected_semi_for);

2223 } else {

2224

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

2228 }

2229 }

2230 }

2231

2232

2233 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&

2235

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

2237

2238 } else if (Tok.is(tok::r_paren)) {

2239

2240 } else {

2242

2243

2244 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();

2248 SecondPart = ParseCXXCondition(

2249 nullptr, ForLoc, CK,

2250

2251 true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,

2252 true);

2253

2254 if (ForRangeInfo.ParsedForRangeDecl()) {

2256 : ForRangeInfo.ColonLoc,

2258 ? diag::warn_cxx17_compat_for_range_init_stmt

2259 : diag::ext_for_range_init_stmt)

2262 if (EmptyInitStmtSemiLoc.isValid()) {

2263 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)

2264 << 2

2266 }

2267 }

2268

2271 SecondPartStart,

2272 Tok.getLocation() == SecondPartStart ? SecondPartStart

2273 : PrevTokLocation,

2277 CondExpr.get(), CK,

2278 false);

2279 }

2280

2281 } else {

2282

2284

2288 else

2292 }

2293 }

2294 }

2295

2296

2297

2300

2301

2302 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {

2303 if (Tok.isNot(tok::semi)) {

2305 Diag(Tok, diag::err_expected_semi_for);

2307 }

2308

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

2311 }

2312

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

2315

2316

2318 }

2319 }

2320

2321 T.consumeClose();

2322

2323

2324

2325 if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {

2326 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);

2328 }

2329

2331 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);

2332

2333

2334

2335

2338

2339 if (ForRangeInfo.ParsedForRangeDecl()) {

2344 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.get(),

2346 ForRangeInfo.LifetimeExtendTemps);

2347 } else if (ForEach) {

2348

2349

2351 ForLoc, FirstPart.get(), Collection.get(), T.getCloseLocation());

2352 } else {

2353

2354

2357 }

2358 }

2359

2360

2361

2363 if (ForRangeInfo.ParsedForRangeDecl())

2365 else

2367 ForLoc, FirstPart.get(), SecondPart.get().second, ThirdPart.get());

2368

2369

2370

2371

2372

2373

2374

2375

2376

2377

2378

2379

2380 ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,

2381 Tok.is(tok::l_brace));

2382

2383

2384

2385

2386

2387 if (C99orCXXorObjC)

2389

2390 MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);

2391

2392

2393 StmtResult Body(ParseStatement(TrailingElseLoc));

2394

2395 if (Body.isUsable())

2396 MIChecker.Check();

2397

2398

2399 InnerScope.Exit();

2400

2402

2403

2404 ForScope.Exit();

2405

2406 if (Body.isInvalid())

2408

2409 if (ForEach)

2411 Body.get());

2412

2413 if (ForRangeInfo.ParsedForRangeDecl())

2415

2416 return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),

2417 SecondPart, ThirdPart, T.getCloseLocation(),

2418 Body.get());

2419}

2420

2421

2422

2423

2424

2425

2426

2427

2428StmtResult Parser::ParseGotoStatement() {

2429 assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");

2431

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

2438 } else if (Tok.is(tok::star)) {

2439

2440 Diag(Tok, diag::ext_gnu_indirect_goto);

2443 if (R.isInvalid()) {

2446 }

2448 } else {

2449 Diag(Tok, diag::err_expected) << tok::identifier;

2451 }

2452

2453 return Res;

2454}

2455

2456

2457

2458

2459

2460

2461

2462StmtResult Parser::ParseContinueStatement() {

2465}

2466

2467

2468

2469

2470

2471

2472

2473StmtResult Parser::ParseBreakStatement() {

2476}

2477

2478

2479

2480

2481

2482

2483

2484StmtResult Parser::ParseReturnStatement() {

2485 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&

2486 "Not a return stmt!");

2487 bool IsCoreturn = Tok.is(tok::kw_co_return);

2489

2491 if (Tok.isNot(tok::semi)) {

2492 if (!IsCoreturn)

2494

2495 if (Tok.is(tok::code_completion) && !IsCoreturn) {

2496 cutOffParsing();

2500 }

2501

2503 R = ParseInitializer();

2507 ? diag::warn_cxx98_compat_generalized_initializer_lists

2508 : diag::ext_generalized_initializer_lists)

2510 } else

2515 }

2516 }

2517 if (IsCoreturn)

2520}

2521

2522StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,

2523 ParsedStmtContext StmtCtx,

2526

2528

2530

2531

2532 while (Tok.is(tok::annot_pragma_loop_hint)) {

2534 if (!HandlePragmaLoopHint(Hint))

2535 continue;

2536

2541 ParsedAttr::Form::Pragma());

2542 }

2543

2544

2545 MaybeParseCXX11Attributes(Attrs);

2546

2548 StmtResult S = ParseStatementOrDeclarationAfterAttributes(

2549 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);

2550

2552

2553

2554

2557

2558 return S;

2559}

2560

2561Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {

2562 assert(Tok.is(tok::l_brace));

2564

2566 "parsing function body");

2567

2568

2569 bool IsCXXMethod =

2572 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);

2573

2574

2575

2576

2577 StmtResult FnBody(ParseCompoundStatementBody());

2578

2579

2580 if (FnBody.isInvalid()) {

2582 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);

2583 }

2584

2585 BodyScope.Exit();

2587}

2588

2589

2590

2591

2592

2593

2594Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {

2595 assert(Tok.is(tok::kw_try) && "Expected 'try'");

2597

2599 "parsing function try block");

2600

2601

2602 if (Tok.is(tok::colon))

2603 ParseConstructorInitializer(Decl);

2604 else

2606

2607

2608 bool IsCXXMethod =

2611 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);

2612

2614 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, true));

2615

2616

2617 if (FnBody.isInvalid()) {

2619 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);

2620 }

2621

2622 BodyScope.Exit();

2624}

2625

2626bool Parser::trySkippingFunctionBody() {

2627 assert(SkipFunctionBodies &&

2628 "Should only be called when SkipFunctionBodies is enabled");

2630 SkipFunctionBody();

2631 return true;

2632 }

2633

2634

2635

2636 TentativeParsingAction PA(*this);

2637 bool IsTryCatch = Tok.is(tok::kw_try);

2639 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);

2640 if (llvm::any_of(Toks, [](const Token &Tok) {

2641 return Tok.is(tok::code_completion);

2642 })) {

2643 PA.Revert();

2644 return false;

2645 }

2646 if (ErrorInPrologue) {

2647 PA.Commit();

2649 return true;

2650 }

2652 PA.Revert();

2653 return false;

2654 }

2655 while (IsTryCatch && Tok.is(tok::kw_catch)) {

2658 PA.Revert();

2659 return false;

2660 }

2661 }

2662 PA.Commit();

2663 return true;

2664}

2665

2666

2667

2668

2669

2670

2671StmtResult Parser::ParseCXXTryBlock() {

2672 assert(Tok.is(tok::kw_try) && "Expected 'try'");

2673

2675 return ParseCXXTryBlockCommon(TryLoc);

2676}

2677

2678

2679

2680

2681

2682

2683

2684

2685

2686

2687

2688

2689

2690

2691

2692

2693

2695 if (Tok.isNot(tok::l_brace))

2696 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);

2697

2698 StmtResult TryBlock(ParseCompoundStatement(

2702 if (TryBlock.isInvalid())

2703 return TryBlock;

2704

2705

2706

2707 if ((Tok.is(tok::identifier) &&

2709 Tok.is(tok::kw___finally)) {

2710

2714 Handler = ParseSEHExceptBlock(Loc);

2715 }

2716 else {

2718 Handler = ParseSEHFinallyBlock(Loc);

2719 }

2721 return Handler;

2722

2724 TryLoc,

2725 TryBlock.get(),

2726 Handler.get());

2727 }

2728 else {

2730

2731

2732

2733 DiagnoseAndSkipCXX11Attributes();

2734

2735 if (Tok.isNot(tok::kw_catch))

2736 return StmtError(Diag(Tok, diag::err_expected_catch));

2737 while (Tok.is(tok::kw_catch)) {

2738 StmtResult Handler(ParseCXXCatchBlock(FnTry));

2740 Handlers.push_back(Handler.get());

2741 }

2742

2743

2744 if (Handlers.empty())

2746

2747 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);

2748 }

2749}

2750

2751

2752

2753

2754

2755

2756

2757

2758

2759

2760

2761StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {

2762 assert(Tok.is(tok::kw_catch) && "Expected 'catch'");

2763

2765

2767 if (T.expectAndConsume())

2769

2770

2771

2772

2776

2777

2778

2779 Decl *ExceptionDecl = nullptr;

2780 if (Tok.isNot(tok::ellipsis)) {

2782 MaybeParseCXX11Attributes(Attributes);

2783

2785

2786 if (ParseCXXTypeSpecifierSeq(DS))

2788

2790 ParseDeclarator(ExDecl);

2792 } else

2794

2795 T.consumeClose();

2796 if (T.getCloseLocation().isInvalid())

2798

2799 if (Tok.isNot(tok::l_brace))

2800 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);

2801

2802

2804 if (Block.isInvalid())

2806

2808}

2809

2810void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {

2811 IfExistsCondition Result;

2812 if (ParseMicrosoftIfExistsCondition(Result))

2813 return;

2814

2815

2816

2817

2818

2819 if (Result.Behavior == IEB_Dependent) {

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

2821 Diag(Tok, diag::err_expected) << tok::l_brace;

2822 return;

2823 }

2824

2825 StmtResult Compound = ParseCompoundStatement();

2827 return;

2828

2833 Compound.get());

2835 Stmts.push_back(DepResult.get());

2836 return;

2837 }

2838

2840 if (Braces.consumeOpen()) {

2841 Diag(Tok, diag::err_expected) << tok::l_brace;

2842 return;

2843 }

2844

2845 switch (Result.Behavior) {

2846 case IEB_Parse:

2847

2848 break;

2849

2850 case IEB_Dependent:

2851 llvm_unreachable("Dependent case handled above");

2852

2853 case IEB_Skip:

2855 return;

2856 }

2857

2858

2859 while (Tok.isNot(tok::r_brace)) {

2861 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);

2863 Stmts.push_back(R.get());

2864 }

2865 Braces.consumeClose();

2866}

enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind

static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt)

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

This file declares facilities that support code completion.

This file declares semantic analysis for Objective-C.

This file declares semantic analysis for OpenACC constructs and clauses.

This file declares semantic analysis for OpenMP constructs and clauses.

static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)

Defines the clang::TokenKind enum and support functions.

Attr - This represents one attribute.

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

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

Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...

virtual bool ValidateCandidate(const TypoCorrection &candidate)

Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...

Captures information about "declaration specifiers".

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

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.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.

Represents a member of a struct/union/class.

Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...

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.

void setIsPoisoned(bool Value=true)

setIsPoisoned - Mark this identifier as poisoned.

StringRef getName() const

Return the actual identifier string.

Represents the declaration of a label.

@ FEM_Source

Use the declared type for fp arithmetic.

Represent a C++ namespace.

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

ParsedAttr - Represents a syntactic attribute.

ParsedAttributes - A collection of parsed attributes.

void takeAllFrom(ParsedAttributes &Other)

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

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Sema::FullExprArg FullExprArg

SourceLocation ConsumeToken()

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

Sema & getActions() const

ExprResult ParseCaseExpression(SourceLocation CaseLoc)

StmtResult ParseOpenACCDirectiveStmt()

bool TryConsumeToken(tok::TokenKind Expected)

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

Scope * getCurScope() const

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 ...

void SkipMalformedDecl()

SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...

const LangOptions & getLangOpts() const

ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)

Simple precedence-based parser for binary/ternary operators.

SmallVector< Stmt *, 32 > StmtVector

A SmallVector of statements.

@ StopBeforeMatch

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

@ StopAtCodeCompletion

Stop at code completion.

@ StopAtSemi

Stop skipping at semicolon.

const Token & NextToken()

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

An RAII object for [un]poisoning an identifier within a scope.

void enterReturn(Sema &S, SourceLocation Tok)

QualType get(SourceLocation Tok) const

Get the expected type associated with this location, if any.

SourceLocation getLastFPEvalPragmaLocation() const

LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const

SourceManager & getSourceManager() const

const TargetInfo & getTargetInfo() const

bool isCodeCompletionEnabled() const

Determine if we are performing code completion.

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

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

PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...

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

void AddFlags(unsigned Flags)

Sets up the specified scope flags and adjusts the scope state variables accordingly.

void decrementMSManglingNumber()

@ SEHTryScope

This scope corresponds to an SEH try.

@ ContinueScope

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

@ ControlScope

The controlling scope in a if/switch/while/for statement.

@ SEHFilterScope

We are currently in the filter expression of an SEH except block.

@ SwitchScope

This is a scope that corresponds to a switch statement.

@ BreakScope

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

@ CatchScope

This is the scope of a C++ catch statement.

@ CompoundStmtScope

This is a compound statement scope.

@ FnTryCatchScope

This is the scope for a function-level C++ try or catch scope.

@ SEHExceptScope

This scope corresponds to an SEH except.

@ TryScope

This is the scope of a C++ try statement.

@ DeclScope

This is a scope that can contain a declaration.

@ PCC_ForInit

Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...

@ PCC_Expression

Code completion occurs within an expression.

@ PCC_Statement

Code completion occurs within a statement, which may also be an expression or a declaration.

void CodeCompleteCase(Scope *S)

void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data)

Perform code-completion in an expression context when we know what type we're looking for.

void CodeCompleteAfterIf(Scope *S, bool IsBracedThen)

void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)

void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar)

StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)

StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)

FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.

Helper type to restore the state of various 'loop' constructs when we run into a loop (for,...

void ActOnWhileStmt(SourceLocation WhileLoc)

void ActOnDoStmt(SourceLocation DoLoc)

void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)

void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)

void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)

void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)

Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...

A RAII object to enter scope of a compound statement.

std::pair< VarDecl *, Expr * > get() const

std::optional< bool > getKnownValue() const

Records and restores the CurFPFeatures state on entry/exit of compound statements.

StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, IdentifierInfo *Ident, ParsedAttributes &Attrs)

StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)

StmtResult ActOnForEachLValueExpr(Expr *E)

In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...

void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)

@ Boolean

A boolean condition, from 'if', 'while', 'for', or 'do'.

@ Switch

An integral condition for a 'switch' statement.

@ ConstexprIf

A constant boolean condition from 'if constexpr'.

StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)

StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)

StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)

bool CheckCaseExpression(Expr *E)

ASTContext & getASTContext() const

StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)

StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)

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

StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)

StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)

SemaCodeCompletion & CodeCompletion()

void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())

ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...

StmtResult ActOnExprStmtError()

StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)

StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)

StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)

Decl * ActOnExceptionDeclarator(Scope *S, Declarator &D)

ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch handler.

LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())

LookupOrCreateLabel - Do a name lookup of a label with the specified name.

Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)

StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})

ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.

void ActOnDefaultCtorInitializers(Decl *CDtorDecl)

DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)

StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)

StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope)

StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)

StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)

StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)

ExpressionEvaluationContext

Describes how the expressions currently being parsed are evaluated at run-time, if at all.

@ DiscardedStatement

The current expression occurs within a discarded statement.

@ ImmediateFunctionContext

In addition of being constant evaluated, the current expression occurs in an immediate function conte...

StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)

void ActOnAfterCompoundStatementLeadingPragmas()

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

StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)

StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope)

FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)

void ActOnStartSEHFinallyBlock()

void ActOnAbortSEHFinallyBlock()

@ BFRK_Build

Initial building of a for-range statement.

StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)

ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...

void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)

ActOnCaseStmtBody - This installs a statement as the body of a case.

ExprResult ActOnStmtExprResult(ExprResult E)

ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())

Attempts to produce a RecoveryExpr after some AST node cannot be created.

StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)

QualType PreferredConditionType(ConditionKind K) const

static ConditionResult ConditionError()

StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)

StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)

StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)

ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...

StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)

StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)

StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)

FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.

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.

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 getBegin() const

Stmt - This represents one statement.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

virtual bool supportSourceEvalMethod() const

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

IdentifierInfo * getIdentifierInfo() const

SourceLocation getLocation() const

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

void setKind(tok::TokenKind K)

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)) {....

tok::TokenKind getKind() const

bool isAtStartOfLine() const

isAtStartOfLine - Return true if this token is at the start of a line.

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

bool isAnnotation() const

Return true if this is any of tok::annot_* kind tokens.

void setAnnotationValue(void *val)

Simple class containing the result of Sema::CorrectTypo.

DeclClass * getCorrectionDeclAs() const

NestedNameSpecifier * getCorrectionSpecifier() const

Gets the NestedNameSpecifier needed to use the typo correction.

Represents a variable declaration or definition.

Defines the clang::TargetInfo interface.

TokenKind

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

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

IfStatementKind

In an if statement, this denotes whether the statement is a constexpr or consteval if statement.

llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion

A union of the various pointer types that can be passed to an ParsedAttr as an argument.

void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)

Consumes the attributes from First and Second and concatenates them into Result.

@ Result

The result type of a method or function.

ActionResult< Stmt * > StmtResult

const FunctionProtoType * T

@ Braces

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

Loop optimization hint for loop and unroll pragmas.

IdentifierLoc * OptionLoc

IdentifierLoc * PragmaNameLoc