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

1

2

3

4

5

6

7

8

9

10

11

12

25#include "llvm/Support/Path.h"

26#include "llvm/Support/TimeProfiler.h"

27using namespace clang;

28

29

30namespace {

31

32

35

36public:

37 explicit ActionCommentHandler(Sema &S) : S(S) { }

38

41 return false;

42 }

43};

44}

45

47

50

51 return Ident__except;

52}

53

55 : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),

56 Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),

57 ColonIsSacred(false), InMessageExpression(false),

58 TemplateParameterDepth(0), ParsingInObjCContainer(false) {

62 Actions.CurScope = nullptr;

63 NumCachedScopes = 0;

64 CurParsedObjCImpl = nullptr;

65

66

67

68 initializePragmaHandlers();

69

70 CommentSemaHandler.reset(new ActionCommentHandler(actions));

72

74

76 [this](StringRef TypeStr, StringRef Context, SourceLocation IncludeLoc) {

77 return this->ParseTypeFromString(TypeStr, Context, IncludeLoc);

78 };

79}

80

83}

84

87}

88

89

90

91

92

93

94

99

100

102 return;

103 }

104

108}

109

111 switch (ExpectedTok) {

112 case tok:🚛

113 return Tok.is(tok::colon) || Tok.is(tok::comma);

114 default: return false;

115 }

116}

117

118bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,

119 StringRef Msg) {

120 if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {

122 return false;

123 }

124

125

128 {

132 if (DiagID == diag::err_expected)

133 DB << ExpectedTok;

134 else if (DiagID == diag::err_expected_after)

135 DB << Msg << ExpectedTok;

136 else

137 DB << Msg;

138 }

139

140

142 return false;

143 }

144

146 const char *Spelling = nullptr;

149

151 Spelling

153 : Diag(Tok, DiagID);

154 if (DiagID == diag::err_expected)

155 DB << ExpectedTok;

156 else if (DiagID == diag::err_expected_after)

157 DB << Msg << ExpectedTok;

158 else

159 DB << Msg;

160

161 return true;

162}

163

164bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) {

166 return false;

167

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

169 handleUnexpectedCodeCompletionToken();

170 return false;

171 }

172

173 if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&

175 Diag(Tok, diag::err_extraneous_token_before_semi)

180 return false;

181 }

182

183 return ExpectAndConsume(tok::semi, DiagID , TokenUsed);

184}

185

186void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {

187 if (!Tok.is(tok::semi)) return;

188

189 bool HadMultipleSemis = false;

193

195 HadMultipleSemis = true;

198 }

199

200

201

204 Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)

206 else

207 Diag(StartLoc, diag::ext_extra_semi_cxx11)

209 return;

210 }

211

212 if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)

213 Diag(StartLoc, diag::ext_extra_semi)

217 else

218

219 Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)

221}

222

223bool Parser::expectIdentifier() {

224 if (Tok.is(tok::identifier))

225 return false;

227 if (II->isCPlusPlusKeyword(getLangOpts())) {

228 Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)

230

231 return false;

232 }

233 }

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

235 return true;

236}

237

238void Parser::checkCompoundToken(SourceLocation FirstTokLoc,

241 return;

243

244

245

249 Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro)

250 << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()

251 << static_cast<int>(Op) << SourceRange(FirstTokLoc);

252 Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here)

255 return;

256 }

257

258

262 SpaceLoc = FirstTokLoc;

263 Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace)

264 << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()

265 << static_cast<int>(Op) << SourceRange(FirstTokLoc, SecondTokLoc);

266 return;

267 }

268}

269

270

271

272

273

275 return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;

276}

277

278

279

280

281

282

283

284

285

287

288

289 bool isFirstTokenSkipped = true;

290 while (true) {

291

292 for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {

293 if (Tok.is(Toks[i])) {

295

296 } else {

298 }

299 return true;

300 }

301 }

302

303

304

305

306 if (Toks.size() == 1 && Toks[0] == tok::eof &&

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

311 return true;

312 }

313

315 case tok::eof:

316

317 return false;

318

319 case tok::annot_pragma_openmp:

320 case tok::annot_attr_openmp:

321 case tok::annot_pragma_openmp_end:

322

323 if (OpenMPDirectiveParsing)

324 return false;

325 ConsumeAnnotationToken();

326 break;

327 case tok::annot_pragma_openacc:

328 case tok::annot_pragma_openacc_end:

329

330 if (OpenACCDirectiveParsing)

331 return false;

332 ConsumeAnnotationToken();

333 break;

334 case tok::annot_module_begin:

335 case tok::annot_module_end:

336 case tok::annot_module_include:

337 case tok::annot_repl_input_end:

338

339

340

341 return false;

342

343 case tok::code_completion:

345 handleUnexpectedCodeCompletionToken();

346 return false;

347

348 case tok::l_paren:

349

350 ConsumeParen();

353 else

355 break;

356 case tok::l_square:

357

358 ConsumeBracket();

361 else

363 break;

364 case tok::l_brace:

365

366 ConsumeBrace();

369 else

371 break;

372 case tok::question:

373

374

379 break;

380

381

382

383

384

385

386 case tok::r_paren:

387 if (ParenCount && !isFirstTokenSkipped)

388 return false;

389 ConsumeParen();

390 break;

391 case tok::r_square:

392 if (BracketCount && !isFirstTokenSkipped)

393 return false;

394 ConsumeBracket();

395 break;

396 case tok::r_brace:

397 if (BraceCount && !isFirstTokenSkipped)

398 return false;

399 ConsumeBrace();

400 break;

401

402 case tok:🚛

404 return false;

405 [[fallthrough]];

406 default:

407

409 break;

410 }

411 isFirstTokenSkipped = false;

412 }

413}

414

415

416

417

418

419

421 if (NumCachedScopes) {

422 Scope *N = ScopeCache[--NumCachedScopes];

424 Actions.CurScope = N;

425 } else {

426 Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags);

427 }

428}

429

430

432 assert(getCurScope() && "Scope imbalance!");

433

434

435

437

439 Actions.CurScope = OldScope->getParent();

440

441 if (NumCachedScopes == ScopeCacheSize)

442 delete OldScope;

443 else

444 ScopeCache[NumCachedScopes++] = OldScope;

445}

446

447

448

449Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,

450 bool ManageFlags)

451 : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {

452 if (CurScope) {

453 OldFlags = CurScope->getFlags();

454 CurScope->setFlags(ScopeFlags);

455 }

456}

457

458

459

460Parser::ParseScopeFlags::~ParseScopeFlags() {

461 if (CurScope)

462 CurScope->setFlags(OldFlags);

463}

464

465

466

467

468

469

471

473 Actions.CurScope = nullptr;

474

475

476 for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)

477 delete ScopeCache[i];

478

479 resetPragmaHandlers();

480

482

484

485 DestroyTemplateIds();

486}

487

488

489

491

492 assert(getCurScope() == nullptr && "A scope is already active?");

495

496

497

507 ObjCTypeQuals[objc_null_unspecified]

509 }

510

511 Ident_instancetype = nullptr;

512 Ident_final = nullptr;

513 Ident_sealed = nullptr;

514 Ident_abstract = nullptr;

515 Ident_override = nullptr;

516 Ident_GNU_final = nullptr;

517 Ident_import = nullptr;

518 Ident_module = nullptr;

519

521

522 Ident_vector = nullptr;

523 Ident_bool = nullptr;

524 Ident_Bool = nullptr;

525 Ident_pixel = nullptr;

530 }

533

534 Ident_introduced = nullptr;

535 Ident_deprecated = nullptr;

536 Ident_obsoleted = nullptr;

537 Ident_unavailable = nullptr;

538 Ident_strict = nullptr;

539 Ident_replacement = nullptr;

540

541 Ident_language = Ident_defined_in = Ident_generated_declaration = Ident_USR =

542 nullptr;

543

544 Ident__except = nullptr;

545

546 Ident__exception_code = Ident__exception_info = nullptr;

547 Ident__abnormal_termination = Ident___exception_code = nullptr;

548 Ident___exception_info = Ident___abnormal_termination = nullptr;

549 Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;

550 Ident_AbnormalTermination = nullptr;

551

554 Ident___exception_info = PP.getIdentifierInfo("__exception_info");

555 Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation");

557 Ident___exception_code = PP.getIdentifierInfo("__exception_code");

558 Ident_GetExceptionCode = PP.getIdentifierInfo("GetExceptionCode");

559 Ident__abnormal_termination = PP.getIdentifierInfo("_abnormal_termination");

560 Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination");

561 Ident_AbnormalTermination = PP.getIdentifierInfo("AbnormalTermination");

562

563 PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block);

564 PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block);

565 PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block);

566 PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter);

567 PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter);

568 PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter);

569 PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block);

570 PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block);

571 PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);

572 }

573

577 }

578

580

581

583}

584

585void Parser::DestroyTemplateIds() {

587 Id->Destroy();

588 TemplateIds.clear();

589}

590

591

592

593

594

595

596

597

598

599

600

604

605

606

609

610

611

612

613

614

617 Diag(diag::ext_empty_translation_unit);

618

619 return NoTopLevelDecls;

620}

621

622

623

624

625

626

627

630 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);

631

634 case tok::annot_pragma_unused:

635 HandlePragmaUnused();

636 return false;

637

638 case tok::kw_export:

640 case tok::kw_module:

641 goto module_decl;

642

643

644

645

646

647

648

649 case tok::identifier: {

651 if ((II == Ident_module || II == Ident_import) &&

652 GetLookAheadToken(2).isNot(tok::coloncolon)) {

653 if (II == Ident_module)

654 goto module_decl;

655 else

656 goto import_decl;

657 }

658 break;

659 }

660

661 default:

662 break;

663 }

664 break;

665

666 case tok::kw_module:

667 module_decl:

668 Result = ParseModuleDecl(ImportState);

669 return false;

670

671 case tok::kw_import:

672 import_decl: {

675 return false;

676 }

677

678 case tok::annot_module_include: {

681

682

685 else {

688 Decl *ImportDecl = Import.isInvalid() ? nullptr : Import.get();

690 }

691 ConsumeAnnotationToken();

692 return false;

693 }

694

695 case tok::annot_module_begin:

699 ConsumeAnnotationToken();

701 return false;

702

703 case tok::annot_module_end:

707 ConsumeAnnotationToken();

709 return false;

710

711 case tok::eof:

712 case tok::annot_repl_input_end:

713

718 if (OverrideLoc.isValid()) {

719 PP.Diag(OverrideLoc, diag::note_max_tokens_total_override);

720 }

721 }

722

723

726

727 return true;

728

729 case tok::identifier:

730

731

732

733

736 NextToken().isNot(tok::coloncolon)) {

738 goto module_decl;

739 else

740 goto import_decl;

741 }

742 break;

743

744 default:

745 break;

746 }

747

750

751

752

753

754 while (MaybeParseCXX11Attributes(DeclAttrs) ||

755 MaybeParseGNUAttributes(DeclSpecAttrs))

756 ;

757

758 Result = ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);

759

760

763

766

768 else if (ImportState ==

770

772 }

773 return false;

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

809 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);

811

813 cutOffParsing();

814 return nullptr;

815 }

816

817 Decl *SingleDecl = nullptr;

819 case tok::annot_pragma_vis:

820 HandlePragmaVisibility();

821 return nullptr;

822 case tok::annot_pragma_pack:

823 HandlePragmaPack();

824 return nullptr;

825 case tok::annot_pragma_msstruct:

826 HandlePragmaMSStruct();

827 return nullptr;

828 case tok::annot_pragma_align:

829 HandlePragmaAlign();

830 return nullptr;

831 case tok::annot_pragma_weak:

832 HandlePragmaWeak();

833 return nullptr;

834 case tok::annot_pragma_weakalias:

835 HandlePragmaWeakAlias();

836 return nullptr;

837 case tok::annot_pragma_redefine_extname:

838 HandlePragmaRedefineExtname();

839 return nullptr;

840 case tok::annot_pragma_fp_contract:

841 HandlePragmaFPContract();

842 return nullptr;

843 case tok::annot_pragma_fenv_access:

844 case tok::annot_pragma_fenv_access_ms:

845 HandlePragmaFEnvAccess();

846 return nullptr;

847 case tok::annot_pragma_fenv_round:

848 HandlePragmaFEnvRound();

849 return nullptr;

850 case tok::annot_pragma_cx_limited_range:

851 HandlePragmaCXLimitedRange();

852 return nullptr;

853 case tok::annot_pragma_float_control:

854 HandlePragmaFloatControl();

855 return nullptr;

856 case tok::annot_pragma_fp:

857 HandlePragmaFP();

858 break;

859 case tok::annot_pragma_opencl_extension:

860 HandlePragmaOpenCLExtension();

861 return nullptr;

862 case tok::annot_attr_openmp:

863 case tok::annot_pragma_openmp: {

865 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);

866 }

867 case tok::annot_pragma_openacc:

869 case tok::annot_pragma_ms_pointers_to_members:

870 HandlePragmaMSPointersToMembers();

871 return nullptr;

872 case tok::annot_pragma_ms_vtordisp:

873 HandlePragmaMSVtorDisp();

874 return nullptr;

875 case tok::annot_pragma_ms_pragma:

876 HandlePragmaMSPragma();

877 return nullptr;

878 case tok::annot_pragma_dump:

879 HandlePragmaDump();

880 return nullptr;

881 case tok::annot_pragma_attribute:

882 HandlePragmaAttribute();

883 return nullptr;

884 case tok:🚛

885

886 SingleDecl =

888 ConsumeExtraSemi(OutsideFunction);

889 break;

890 case tok::r_brace:

891 Diag(Tok, diag::err_extraneous_closing_brace);

892 ConsumeBrace();

893 return nullptr;

894 case tok::eof:

895 Diag(Tok, diag::err_expected_external_declaration);

896 return nullptr;

897 case tok::kw___extension__: {

898

901 return ParseExternalDeclaration(Attrs, DeclSpecAttrs);

902 }

903 case tok::kw_asm: {

904 ProhibitAttributes(Attrs);

905

908

909 ExprResult Result(ParseSimpleAsm( false, &EndLoc));

910

911

912

913

915 const auto *SL = cast(Result.get());

916 if (!SL->getString().trim().empty())

917 Diag(StartLoc, diag::err_gnu_inline_asm_disabled);

918 }

919

920 ExpectAndConsume(tok::semi, diag::err_expected_after,

921 "top-level asm block");

922

923 if (Result.isInvalid())

924 return nullptr;

926 break;

927 }

928 case tok::at:

929 return ParseObjCAtDirectives(Attrs, DeclSpecAttrs);

930 case tok:âž–

931 case tok:âž•

933 Diag(Tok, diag::err_expected_external_declaration);

935 return nullptr;

936 }

937 SingleDecl = ParseObjCMethodDefinition();

938 break;

939 case tok::code_completion:

940 cutOffParsing();

941 if (CurParsedObjCImpl) {

942

945 std::nullopt,

946 nullptr);

947 }

948

950 if (CurParsedObjCImpl) {

954 } else {

956 };

958 return nullptr;

959 case tok::kw_import: {

962 llvm_unreachable("not expecting a c++20 import here");

963 ProhibitAttributes(Attrs);

964 }

965 SingleDecl = ParseModuleImport(SourceLocation(), IS);

966 } break;

967 case tok::kw_export:

969 ProhibitAttributes(Attrs);

970 SingleDecl = ParseExportDeclaration();

971 break;

972 }

973

974

975 [[fallthrough]];

976 case tok::kw_using:

977 case tok::kw_namespace:

978 case tok::kw_typedef:

979 case tok::kw_template:

980 case tok::kw_static_assert:

981 case tok::kw__Static_assert:

982

983 {

986 DeclSpecAttrs);

987 }

988

989 case tok::kw_cbuffer:

990 case tok::kw_tbuffer:

994 DeclSpecAttrs);

995 }

996 goto dont_know;

997

998 case tok::kw_static:

999

1000

1002 Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)

1003 << 0;

1006 DeclSpecAttrs);

1007 }

1008 goto dont_know;

1009

1010 case tok::kw_inline:

1013

1014

1015 if (NextKind == tok::kw_namespace) {

1018 DeclSpecAttrs);

1019 }

1020

1021

1022

1023 if (NextKind == tok::kw_template) {

1024 Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)

1025 << 1;

1028 DeclSpecAttrs);

1029 }

1030 }

1031 goto dont_know;

1032

1033 case tok::kw_extern:

1035

1039 diag::warn_cxx98_compat_extern_template :

1040 diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);

1043 TemplateLoc, DeclEnd, Attrs);

1044 }

1045 goto dont_know;

1046

1047 case tok::kw___if_exists:

1048 case tok::kw___if_not_exists:

1049 ParseMicrosoftIfExistsExternalDeclaration();

1050 return nullptr;

1051

1052 case tok::kw_module:

1053 Diag(Tok, diag::err_unexpected_module_decl);

1055 return nullptr;

1056

1057 default:

1058 dont_know:

1061 return nullptr;

1062 }

1063 if (getLangOpts().IncrementalExtensions &&

1064 !isDeclarationStatement(true))

1065 return ParseTopLevelStmtDecl();

1066

1067

1068 if (!SingleDecl)

1069 return ParseDeclarationOrFunctionDefinition(Attrs, DeclSpecAttrs, DS);

1070 }

1071

1072

1073

1075}

1076

1077

1078

1079bool Parser::isDeclarationAfterDeclarator() {

1080

1083 if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))

1084 return false;

1085 }

1086

1087 return Tok.is(tok::equal) ||

1088 Tok.is(tok::comma) ||

1089 Tok.is(tok::semi) ||

1090 Tok.is(tok::kw_asm) ||

1091 Tok.is(tok::kw___attribute) ||

1093 Tok.is(tok::l_paren));

1094}

1095

1096

1097

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

1101 return true;

1102

1103

1107

1110 return KW.is(tok::kw_default) || KW.is(tok::kw_delete);

1111 }

1112

1113 return Tok.is(tok::colon) ||

1114 Tok.is(tok::kw_try);

1115}

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130

1131

1132

1136

1137

1138

1140 "expected uninitialised source range");

1144

1145 ParsedTemplateInfo TemplateInfo;

1146 MaybeParseMicrosoftAttributes(DS.getAttributes());

1147

1148 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,

1149 DeclSpecContext::DSC_top_level);

1150

1151

1152

1153 if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(

1154 DS, AS, DeclSpecContext::DSC_top_level))

1155 return nullptr;

1156

1157

1158

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

1160 auto LengthOfTSTToken = [](DeclSpec::TST TKind) {

1162 switch(TKind) {

1164 return 5;

1166 return 6;

1168 return 5;

1170 return 4;

1172 return 9;

1173 default:

1174 llvm_unreachable("we only expect to get the length of the class/struct/union/enum");

1175 }

1176

1177 };

1178

1184 ProhibitAttributes(Attrs, CorrectLocationForAttributes);

1191 if (AnonRecord) {

1192 Decl* decls[] = {AnonRecord, TheDecl};

1194 }

1196 }

1197

1200

1201

1202

1203

1209 Diag(Tok, diag::err_objc_unexpected_attr);

1211 return nullptr;

1212 }

1213

1216

1217 const char *PrevSpec = nullptr;

1218 unsigned DiagID;

1221 Diag(AtLoc, DiagID) << PrevSpec;

1222

1224 return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());

1225

1227 return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes());

1228

1230 ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()));

1231 }

1232

1233

1234

1235

1239 ProhibitAttributes(Attrs);

1242 }

1243

1245}

1246

1250

1251

1252 llvm::TimeTraceScope TimeScope("ParseDeclarationOrFunctionDefinition", [&]() {

1255 });

1256

1257 if (DS) {

1258 return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS);

1259 } else {

1261

1262

1263

1265

1266 return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, PDS, AS);

1267 }

1268}

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1285 const ParsedTemplateInfo &TemplateInfo,

1286 LateParsedAttrList *LateParsedAttrs) {

1287 llvm::TimeTraceScope TimeScope("ParseFunctionDefinition", [&]() {

1289 });

1290

1291

1294 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);

1295

1296

1297

1298

1299 if (getLangOpts().isImplicitIntRequired() && D.getDeclSpec().isEmpty()) {

1300 Diag(D.getIdentifierLoc(), diag::warn_missing_type_specifier)

1302 const char *PrevSpec;

1303 unsigned DiagID;

1306 D.getIdentifierLoc(),

1307 PrevSpec, DiagID,

1308 Policy);

1310 }

1311

1312

1313

1314

1316 ParseKNRParamDeclarations(D);

1317

1318

1319

1320 if (Tok.isNot(tok::l_brace) &&

1322 (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&

1323 Tok.isNot(tok::equal)))) {

1324 Diag(Tok, diag::err_expected_fn_body);

1325

1326

1328

1329

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

1331 return nullptr;

1332 }

1333

1334

1335

1336 if (Tok.isNot(tok::equal)) {

1337 for (const ParsedAttr &AL : D.getAttributes())

1338 if (AL.isKnownToGCC() && !AL.isStandardAttributeSyntax())

1339 Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) << AL;

1340 }

1341

1342

1343

1344 if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&

1345 TemplateInfo.Kind == ParsedTemplateInfo::Template &&

1348

1352

1356 D.complete(DP);

1357 D.getMutableDeclSpec().abort();

1358

1360 trySkippingFunctionBody()) {

1361 BodyScope.Exit();

1363 }

1364

1366 LexTemplateFunctionForLateParsing(Toks);

1367

1368 if (DP) {

1372 }

1373 return DP;

1374 }

1375 else if (CurParsedObjCImpl &&

1376 !TemplateInfo.TemplateParams &&

1377 (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||

1378 Tok.is(tok::colon)) &&

1383

1387 D.complete(FuncDecl);

1388 D.getMutableDeclSpec().abort();

1389 if (FuncDecl) {

1390

1391 StashAwayMethodOrFunctionBodyTokens(FuncDecl);

1392 CurParsedObjCImpl->HasCFunction = true;

1393 return FuncDecl;

1394 }

1395

1396 }

1397

1398

1401

1402

1403

1408 assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");

1409

1412 ? diag::warn_cxx98_compat_defaulted_deleted_function

1413 : diag::ext_defaulted_deleted_function)

1414 << 1 ;

1416 DeletedMessage = ParseCXXDeletedFunctionMessage();

1419 ? diag::warn_cxx98_compat_defaulted_deleted_function

1420 : diag::ext_defaulted_deleted_function)

1421 << 0 ;

1423 } else {

1424 llvm_unreachable("function definition after = not 'delete' or 'default'");

1425 }

1426

1427 if (Tok.is(tok::comma)) {

1428 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)

1431 } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,

1433 ? "delete"

1434 : "default")) {

1436 }

1437 }

1438

1440

1441

1442

1445 TemplateInfo.TemplateParams

1446 ? *TemplateInfo.TemplateParams

1448 &SkipBody, BodyKind);

1449

1451

1453 SkipFunctionBody();

1454

1455

1456

1457

1458

1459

1460

1461

1462

1463

1466 return Res;

1467 }

1468

1469

1470 D.complete(Res);

1471

1472

1473

1474 D.getMutableDeclSpec().abort();

1475

1478 Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;

1480 return Res;

1481 }

1482

1483

1484

1485 if (const auto *Template = dyn_cast_if_present(Res);

1486 Template && Template->isAbbreviated() &&

1487 Template->getTemplateParameters()->getParam(0)->isImplicit())

1488

1489

1490 CurTemplateDepthTracker.addDepth(1);

1491

1493 trySkippingFunctionBody()) {

1494 BodyScope.Exit();

1497 }

1498

1499 if (Tok.is(tok::kw_try))

1500 return ParseFunctionTryBlock(Res, BodyScope);

1501

1502

1503

1504 if (Tok.is(tok::colon)) {

1505 ParseConstructorInitializer(Res);

1506

1507

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

1509 BodyScope.Exit();

1511 return Res;

1512 }

1513 } else

1515

1516

1517 if (LateParsedAttrs)

1518 ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);

1519

1520 return ParseFunctionStatementBody(Res, BodyScope);

1521}

1522

1523void Parser::SkipFunctionBody() {

1524 if (Tok.is(tok::equal)) {

1526 return;

1527 }

1528

1529 bool IsFunctionTryBlock = Tok.is(tok::kw_try);

1530 if (IsFunctionTryBlock)

1532

1534 if (ConsumeAndStoreFunctionPrologue(Skipped))

1536 else {

1538 while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {

1541 }

1542 }

1543}

1544

1545

1546

1547void Parser::ParseKNRParamDeclarations(Declarator &D) {

1548

1550

1551

1552

1555

1556

1559

1560

1562 ParsedTemplateInfo TemplateInfo;

1563 ParseDeclarationSpecifiers(DS, TemplateInfo);

1564

1565

1566

1567

1568

1569

1571 Diag(DSStart, diag::err_declaration_does_not_declare_param);

1572 continue;

1573 }

1574

1575

1576

1580 diag::err_invalid_storage_class_in_func_decl);

1582 }

1585 diag::err_invalid_storage_class_in_func_decl);

1587 }

1588

1589

1592 ParseDeclarator(ParmDeclarator);

1593

1594

1595 while (true) {

1596

1597 MaybeParseGNUAttributes(ParmDeclarator);

1598

1599

1600 Decl *Param =

1602

1603 if (Param &&

1604

1605 ParmDeclarator.getIdentifier()) {

1606

1607

1608

1609 for (unsigned i = 0; ; ++i) {

1610

1611

1613 Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)

1614 << ParmDeclarator.getIdentifier();

1615 break;

1616 }

1617

1618 if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) {

1619

1621 Diag(ParmDeclarator.getIdentifierLoc(),

1622 diag::err_param_redefinition)

1623 << ParmDeclarator.getIdentifier();

1624 } else {

1626 }

1627 break;

1628 }

1629 }

1630 }

1631

1632

1633

1634 if (Tok.isNot(tok::comma))

1635 break;

1636

1637 ParmDeclarator.clear();

1638

1639

1641

1642

1643 ParseDeclarator(ParmDeclarator);

1644 }

1645

1646

1647 if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration))

1648 continue;

1649

1650

1652 break;

1654 }

1655

1656

1658}

1659

1660

1661

1662

1663

1664

1665

1666

1667

1668

1669

1670ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {

1671 if (!isTokenStringLiteral()) {

1672 Diag(Tok, diag::err_expected_string_literal)

1673 << 0 << "'asm'";

1675 }

1676

1678 if (!AsmString.isInvalid()) {

1679 const auto *SL = cast(AsmString.get());

1680 if (!SL->isOrdinary()) {

1681 Diag(Tok, diag::err_asm_operand_wide_string_literal)

1682 << SL->isWide()

1683 << SL->getSourceRange();

1685 }

1686 if (ForAsmLabel && SL->getString().empty()) {

1687 Diag(Tok, diag::err_asm_operand_wide_string_literal)

1688 << 2 << SL->getSourceRange();

1690 }

1691 }

1692 return AsmString;

1693}

1694

1695

1696

1697

1698

1699

1701 assert(Tok.is(tok::kw_asm) && "Not an asm!");

1703

1704 if (isGNUAsmQualifier(Tok)) {

1705

1708 Diag(Tok, diag::err_global_asm_qualifier_ignored)

1709 << GNUAsmQualifiers::getQualifierName(getGNUAsmQualifier(Tok))

1712 }

1713

1715 if (T.consumeOpen()) {

1716 Diag(Tok, diag::err_expected_lparen_after) << "asm";

1718 }

1719

1721

1722 if (Result.isInvalid()) {

1723

1724 T.consumeClose();

1725 if (EndLoc)

1726 *EndLoc = T.getCloseLocation();

1728 if (EndLoc)

1730 ConsumeParen();

1731 }

1732

1734}

1735

1736

1737

1738

1740 assert(tok.is(tok::annot_template_id) && "Expected template-id token");

1743 return Id;

1744}

1745

1746void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {

1747

1748

1751 else

1752 PP.EnterToken(Tok, true);

1753 Tok.setKind(tok::annot_cxxscope);

1756

1757

1758

1759

1760 if (IsNewAnnotation)

1762}

1763

1764

1765

1766

1767

1768

1769

1770

1771

1772

1773

1774Parser::AnnotatedNameKind

1777 assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));

1778

1779 const bool EnteringContext = false;

1780 const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);

1781

1784 ParseOptionalCXXScopeSpecifier(SS, nullptr,

1785 false,

1786 EnteringContext))

1787 return ANK_Error;

1788

1791 AllowImplicitTypename))

1792 return ANK_Error;

1793 return ANK_Unresolved;

1794 }

1795

1798

1799

1800

1801 if (isTentativelyDeclared(Name) && SS.isEmpty()) {

1802

1803

1805 AllowImplicitTypename))

1806 return ANK_Error;

1807 return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;

1808 }

1809

1811

1812

1813

1814

1815

1817 getCurScope(), SS, Name, NameLoc, Next, SS.isEmpty() ? CCC : nullptr);

1818

1819

1820

1821

1822

1824 isTemplateArgumentList(1) == TPResult::False) {

1825

1826 Token FakeNext = Next;

1827 FakeNext.setKind(tok::unknown);

1828 Classification =

1830 SS.isEmpty() ? CCC : nullptr);

1831 }

1832

1833 switch (Classification.getKind()) {

1835 return ANK_Error;

1836

1838

1840 Tok.setKind(Name->getTokenID());

1843 AnnotateScopeToken(SS, !WasScopeAnnotation);

1844

1845 return ANK_Success;

1846

1848

1849 break;

1850

1852 if (TryAltiVecVectorToken())

1853

1854

1855

1856 break;

1860

1861

1862

1867

1871 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,

1872 false,

1873 NewEndLoc);

1875 Ty = NewType.get();

1876 else if (Tok.is(tok::eof))

1877 return ANK_Error;

1878 }

1879

1880 Tok.setKind(tok::annot_typename);

1881 setTypeAnnotation(Tok, Ty);

1885 return ANK_Success;

1886 }

1887

1889 Tok.setKind(tok::annot_overload_set);

1890 setExprAnnotation(Tok, Classification.getExpression());

1895 return ANK_Success;

1896

1898 if (TryAltiVecVectorToken())

1899

1900

1901

1902 break;

1903 Tok.setKind(tok::annot_non_type);

1904 setNonTypeAnnotation(Tok, Classification.getNonTypeDecl());

1909 AnnotateScopeToken(SS, !WasScopeAnnotation);

1910 return ANK_Success;

1911

1915 ? tok::annot_non_type_undeclared

1916 : tok::annot_non_type_dependent);

1917 setIdentifierAnnotation(Tok, Name);

1922 AnnotateScopeToken(SS, !WasScopeAnnotation);

1923 return ANK_Success;

1924

1926 if (Next.isNot(tok::less)) {

1927

1929 AnnotateScopeToken(SS, !WasScopeAnnotation);

1930 return ANK_TemplateName;

1931 }

1932 [[fallthrough]];

1938

1939

1940 if (Next.is(tok::less))

1943 Id.setIdentifier(Name, NameLoc);

1944 if (AnnotateTemplateIdToken(

1947 !IsConceptName,

1948 IsConceptName))

1949 return ANK_Error;

1951 AnnotateScopeToken(SS, !WasScopeAnnotation);

1952 return ANK_Success;

1953 }

1954 }

1955

1956

1958 AnnotateScopeToken(SS, !WasScopeAnnotation);

1959 return ANK_Unresolved;

1960}

1961

1962bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {

1963 assert(Tok.isNot(tok::identifier));

1964 Diag(Tok, diag::ext_keyword_as_ident)

1966 << DisableKeyword;

1967 if (DisableKeyword)

1969 Tok.setKind(tok::identifier);

1970 return true;

1971}

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981

1982

1983

1984

1985

1986

1987

1988

1989

1990

1991

1992

1993

1994

1997 assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||

1998 Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||

1999 Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||

2000 Tok.is(tok::kw___super) || Tok.is(tok::kw_auto) ||

2001 Tok.is(tok::annot_pack_indexing_type)) &&

2002 "Cannot be a type or scope token!");

2003

2004 if (Tok.is(tok::kw_typename)) {

2005

2006

2007

2008

2009

2010

2012 Token TypedefToken;

2013 PP.Lex(TypedefToken);

2015 PP.EnterToken(Tok, true);

2016 Tok = TypedefToken;

2018 Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);

2020 }

2021

2022

2023

2024

2025

2026

2027

2030 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

2031 false,

2032 false, nullptr,

2033 true))

2034 return true;

2036 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||

2037 Tok.is(tok::annot_decltype)) {

2038

2039 if (Tok.is(tok::annot_decltype) ||

2042 unsigned DiagID = diag::err_expected_qualified_after_typename;

2043

2044

2046 DiagID = diag::warn_expected_qualified_after_typename;

2048 return false;

2049 }

2050 }

2052 return true;

2053

2054 Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);

2055 return true;

2056 }

2057

2058 bool TemplateKWPresent = false;

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

2061 TemplateKWPresent = true;

2062 }

2063

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

2066 if (TemplateKWPresent && NextToken().isNot(tok::less)) {

2068 diag::missing_template_arg_list_after_template_kw);

2069 return true;

2070 }

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

2077 Diag(Tok, diag::err_typename_refers_to_non_type_template)

2079 return true;

2080 }

2081

2084

2091 TemplateArgsPtr, TemplateId->RAngleLoc);

2092 } else {

2093 Diag(Tok, diag::err_expected_type_name_after_typename)

2095 return true;

2096 }

2097

2099 Tok.setKind(tok::annot_typename);

2100 setTypeAnnotation(Tok, Ty);

2104 return false;

2105 }

2106

2107

2108 bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);

2109

2112 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

2113 false,

2114 false))

2115 return true;

2116

2118 AllowImplicitTypename);

2119}

2120

2121

2122

2123

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

2128

2131 false, NextToken().is(tok::period), nullptr,

2132 false,

2133 true,

2134 true, AllowImplicitTypename)) {

2136 if (SS.isNotEmpty())

2138

2139

2140

2144

2148 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,

2149 false,

2150 NewEndLoc);

2152 Ty = NewType.get();

2153 else if (Tok.is(tok::eof))

2154 return false;

2155 }

2156

2157

2158

2159 Tok.setKind(tok::annot_typename);

2160 setTypeAnnotation(Tok, Ty);

2163

2164

2165

2167 return false;

2168 }

2169

2171

2172

2173

2174 return false;

2175 }

2176

2177

2178

2179

2180 if (NextToken().is(tok::less)) {

2184 bool MemberOfUnknownSpecialization;

2188 nullptr, false, Template,

2189 MemberOfUnknownSpecialization)) {

2190

2191

2193 isTemplateArgumentList(1) != TPResult::False) {

2194

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

2198

2199

2200

2201 return true;

2202 }

2203 }

2204 }

2205 }

2206

2207

2208

2209

2210

2211 }

2212

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

2216

2217

2218

2219

2220 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);

2221 return false;

2222 }

2223 }

2224

2227 Tok.is(tok::coloncolon)) {

2228

2230 return true;

2231 }

2232 return false;

2233 }

2234

2235

2236 AnnotateScopeToken(SS, IsNewScope);

2237 return false;

2238}

2239

2240

2241

2242

2243

2244

2245

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

2250

2252 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

2253 false,

2254 EnteringContext))

2255 return true;

2257 return false;

2258

2259 AnnotateScopeToken(SS, true);

2260 return false;

2261}

2262

2263bool Parser::isTokenEqualOrEqualTypo() {

2265 switch (Kind) {

2266 default:

2267 return false;

2268 case tok::ampequal:

2269 case tok::starequal:

2270 case tok::plusequal:

2271 case tok::minusequal:

2272 case tok::exclaimequal:

2273 case tok::slashequal:

2274 case tok::percentequal:

2275 case tok::lessequal:

2276 case tok::lesslessequal:

2277 case tok::greaterequal:

2278 case tok::greatergreaterequal:

2279 case tok::caretequal:

2280 case tok::pipeequal:

2281 case tok::equalequal:

2282 Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)

2283 << Kind

2285 [[fallthrough]];

2286 case tok::equal:

2287 return true;

2288 }

2289}

2290

2291SourceLocation Parser::handleUnexpectedCodeCompletionToken() {

2292 assert(Tok.is(tok::code_completion));

2294

2296 if (S->isFunctionScope()) {

2297 cutOffParsing();

2300 return PrevTokLocation;

2301 }

2302

2303 if (S->isClassScope()) {

2304 cutOffParsing();

2307 return PrevTokLocation;

2308 }

2309 }

2310

2311 cutOffParsing();

2314 return PrevTokLocation;

2315}

2316

2317

2318

2319void Parser::CodeCompleteDirective(bool InConditional) {

2321}

2322

2323void Parser::CodeCompleteInConditionalExclusion() {

2326}

2327

2328void Parser::CodeCompleteMacroName(bool IsDefinition) {

2330}

2331

2332void Parser::CodeCompletePreprocessorExpression() {

2334}

2335

2336void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,

2338 unsigned ArgumentIndex) {

2341}

2342

2343void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {

2345}

2346

2347void Parser::CodeCompleteNaturalLanguage() {

2349}

2350

2351bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {

2352 assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&

2353 "Expected '__if_exists' or '__if_not_exists'");

2354 Result.IsIfExists = Tok.is(tok::kw___if_exists);

2356

2358 if (T.consumeOpen()) {

2359 Diag(Tok, diag::err_expected_lparen_after)

2360 << (Result.IsIfExists? "__if_exists" : "__if_not_exists");

2361 return true;

2362 }

2363

2364

2366 ParseOptionalCXXScopeSpecifier(Result.SS, nullptr,

2367 false,

2368 false);

2369

2370

2371 if (Result.SS.isInvalid()) {

2372 T.skipToEnd();

2373 return true;

2374 }

2375

2376

2377 SourceLocation TemplateKWLoc;

2379 false, false,

2380 true,

2381 true,

2382 false, &TemplateKWLoc,

2384 T.skipToEnd();

2385 return true;

2386 }

2387

2388 if (T.consumeClose())

2389 return true;

2390

2391

2396 Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip;

2397 break;

2398

2400 Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip;

2401 break;

2402

2404 Result.Behavior = IEB_Dependent;

2405 break;

2406

2408 return true;

2409 }

2410

2411 return false;

2412}

2413

2414void Parser::ParseMicrosoftIfExistsExternalDeclaration() {

2415 IfExistsCondition Result;

2416 if (ParseMicrosoftIfExistsCondition(Result))

2417 return;

2418

2420 if (Braces.consumeOpen()) {

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

2422 return;

2423 }

2424

2425 switch (Result.Behavior) {

2426 case IEB_Parse:

2427

2428 break;

2429

2430 case IEB_Dependent:

2431 llvm_unreachable("Cannot have a dependent external declaration");

2432

2433 case IEB_Skip:

2435 return;

2436 }

2437

2438

2439

2440 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {

2442 MaybeParseCXX11Attributes(Attrs);

2444 DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs);

2447 }

2448 Braces.consumeClose();

2449}

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2463

2467

2471

2472 assert(

2473 (Tok.is(tok::kw_module) ||

2474 (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) &&

2475 "not a module declaration");

2477

2478

2479

2480 DiagnoseAndSkipCXX11Attributes();

2481

2482

2483 if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {

2486 Diag(StartLoc, diag::err_global_module_introducer_not_at_start)

2488 return nullptr;

2489 }

2491 Diag(StartLoc, diag::err_module_fragment_exported)

2493 }

2496 }

2497

2498

2499 if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) &&

2500 NextToken().is(tok::kw_private)) {

2502 Diag(StartLoc, diag::err_module_fragment_exported)

2504 }

2507 DiagnoseAndSkipCXX11Attributes();

2508 ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);

2513 }

2514

2516 if (ParseModuleName(ModuleLoc, Path, false))

2517 return nullptr;

2518

2519

2521 if (Tok.is(tok::colon)) {

2524 Diag(ColonLoc, diag::err_unsupported_module_partition)

2525 << SourceRange(ColonLoc, Partition.back().second);

2526

2527 else if (ParseModuleName(ModuleLoc, Partition, false))

2528 return nullptr;

2529 }

2530

2531

2533 MaybeParseCXX11Attributes(Attrs);

2534 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr,

2535 diag::err_keyword_not_module_attr,

2536 false,

2537 true);

2538

2539 ExpectAndConsumeSemi(diag::err_module_expected_semi);

2540

2541 return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, Partition,

2542 ImportState);

2543}

2544

2545

2546

2547

2548

2549

2550

2551

2552

2553

2554

2555

2556

2557

2558

2559

2563

2566

2567 assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier)

2569 "Improper start to module import");

2570 bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);

2572

2573

2575 bool IsPartition = false;

2576 Module *HeaderUnit = nullptr;

2577 if (Tok.is(tok::header_name)) {

2578

2579

2580

2582 } else if (Tok.is(tok::annot_header_unit)) {

2583

2585 ConsumeAnnotationToken();

2586 } else if (Tok.is(tok::colon)) {

2589 Diag(ColonLoc, diag::err_unsupported_module_partition)

2591

2592 else if (ParseModuleName(ColonLoc, Path, true))

2593 return nullptr;

2594 else

2595 IsPartition = true;

2596 } else {

2597 if (ParseModuleName(ImportLoc, Path, true))

2598 return nullptr;

2599 }

2600

2602 MaybeParseCXX11Attributes(Attrs);

2603

2604 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr,

2605 diag::err_keyword_not_import_attr,

2606 false,

2607 true);

2608

2610

2611 cutOffParsing();

2612 return nullptr;

2613 }

2614

2615

2616 bool SeenError = true;

2617 switch (ImportState) {

2619 SeenError = false;

2620 break;

2622

2623

2625 [[fallthrough]];

2627

2628 if (IsPartition)

2629 Diag(ImportLoc, diag::err_partition_import_outside_module);

2630 else

2631 SeenError = false;

2632 break;

2635

2636

2637

2638

2639

2640

2641 if (IsPartition || (HeaderUnit && HeaderUnit->Kind !=

2643 Diag(ImportLoc, diag::err_import_in_wrong_fragment)

2644 << IsPartition

2646 else

2647 SeenError = false;

2648 break;

2652 Diag(ImportLoc, diag::err_import_not_allowed_here);

2653 else

2654 SeenError = false;

2655 break;

2656 }

2657 ExpectAndConsumeSemi(diag::err_module_expected_semi);

2658

2659 if (SeenError)

2660 return nullptr;

2661

2663 if (HeaderUnit)

2665 Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit);

2666 else if (Path.empty())

2668 IsPartition);

2669 if (Import.isInvalid())

2670 return nullptr;

2671

2672

2673

2674 if (IsObjCAtImport && AtLoc.isValid()) {

2677 if (FE && llvm::sys::path::parent_path(FE->getDir().getName())

2678 .ends_with(".framework"))

2679 Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);

2680 }

2681

2682 return Import.get();

2683}

2684

2685

2686

2687

2688

2689

2690

2691

2692bool Parser::ParseModuleName(

2695 bool IsImport) {

2696

2697 while (true) {

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

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

2700 cutOffParsing();

2702 return true;

2703 }

2704

2705 Diag(Tok, diag::err_module_expected_ident) << IsImport;

2707 return true;

2708 }

2709

2710

2713

2714 if (Tok.isNot(tok::period))

2715 return false;

2716

2718 }

2719}

2720

2721

2722

2723

2724

2725bool Parser::parseMisplacedModuleImport() {

2726 while (true) {

2727 switch (Tok.getKind()) {

2728 case tok::annot_module_end:

2729

2730

2731

2732 if (MisplacedModuleBeginCount) {

2733 --MisplacedModuleBeginCount;

2737 ConsumeAnnotationToken();

2738 continue;

2739 }

2740

2741

2742

2743 return true;

2744 case tok::annot_module_begin:

2745

2749 ConsumeAnnotationToken();

2750 ++MisplacedModuleBeginCount;

2751 continue;

2752 case tok::annot_module_include:

2753

2754

2758 ConsumeAnnotationToken();

2759

2760 continue;

2761 default:

2762 return false;

2763 }

2764 }

2765 return false;

2766}

2767

2768void Parser::diagnoseUseOfC11Keyword(const Token &Tok) {

2769

2770

2771

2773 : diag::ext_c11_feature)

2775}

2776

2777bool BalancedDelimiterTracker::diagnoseOverflow() {

2778 P.Diag(P.Tok, diag::err_bracket_depth_exceeded)

2780 P.Diag(P.Tok, diag::note_bracket_depth);

2781 P.cutOffParsing();

2782 return true;

2783}

2784

2786 const char *Msg,

2789 if (P.ExpectAndConsume(Kind, DiagID, Msg)) {

2790 if (SkipToTok != tok::unknown)

2792 return true;

2793 }

2794

2795 if (getDepth() < P.getLangOpts().BracketDepth)

2796 return false;

2797

2798 return diagnoseOverflow();

2799}

2800

2801bool BalancedDelimiterTracker::diagnoseMissingClose() {

2802 assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");

2803

2804 if (P.Tok.is(tok::annot_module_end))

2805 P.Diag(P.Tok, diag::err_missing_before_module_end) << Close;

2806 else

2807 P.Diag(P.Tok, diag::err_expected) << Close;

2808 P.Diag(LOpen, diag::note_matching) << Kind;

2809

2810

2811

2812 if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&

2813 P.Tok.isNot(tok::r_square) &&

2816 P.Tok.is(Close))

2818 return true;

2819}

2820

2824}

Defines the clang::ASTContext interface.

This file provides some common utility functions for processing Lambda related AST Constructs.

static Decl::Kind getKind(const Decl *D)

Defines the C++ template declaration subclasses.

Defines the clang::FileManager interface and associated types.

static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok)

static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R)

static std::string getName(const CallEvent &Call)

This file declares facilities that support code completion.

virtual bool HandleTopLevelDecl(DeclGroupRef D)

HandleTopLevelDecl - Handle the specified top-level declaration.

SourceManager & getSourceManager()

const clang::PrintingPolicy & getPrintingPolicy() const

ExternalASTSource * getExternalSource() const

Retrieve a pointer to the external AST source associated with this AST context, if any.

The result of parsing/analyzing an expression, statement etc.

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

bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)

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

An error occurred during parsing of the scope specifier.

bool isEmpty() const

No scope specifier.

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

bool isTranslationUnit() const

Captures information about "declaration specifiers".

void ClearStorageClassSpecs()

TST getTypeSpecType() const

SourceLocation getStorageClassSpecLoc() const

SCS getStorageClassSpec() const

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

SourceRange getSourceRange() const LLVM_READONLY

void SetRangeEnd(SourceLocation Loc)

static const TST TST_interface

void SetRangeStart(SourceLocation Loc)

static const TST TST_union

TSCS getThreadStorageClassSpec() const

ParsedAttributes & getAttributes()

static const TST TST_enum

static bool isDeclRep(TST T)

static const TST TST_class

bool hasTagDefinition() const

unsigned getParsedSpecifiers() const

Return a bitmask of which flavors of specifiers this DeclSpec includes.

static const TSCS TSCS_unspecified

static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)

Turn a type-specifier-type into a string like "_Bool" or "union".

SourceLocation getThreadStorageClassSpecLoc() const

Decl * getRepAsDecl() const

static const TST TST_unspecified

SourceLocation getTypeSpecTypeLoc() const

void takeAttributesFrom(ParsedAttributes &attrs)

@ PQ_StorageClassSpecifier

static const TST TST_struct

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

virtual Stmt * getBody() const

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

FunctionDecl * getAsFunction() LLVM_READONLY

Returns the function itself, or the templated function if this is a function template.

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

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

bool isFunctionDeclarator(unsigned &idx) const

isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...

DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()

getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).

A little helper class used to produce diagnostics.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

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

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.

Represents a function declaration or definition.

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

void revertTokenIDToIdentifier()

Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

Describes a module import declaration, which makes the contents of the named module visible in the cu...

Encapsulates the data about a macro definition (e.g.

Describes a module or submodule.

ModuleKind Kind

The kind of this module.

bool isHeaderUnit() const

Is this module a header unit.

@ ModuleHeaderUnit

This is a C++20 header unit.

Wrapper for void* pointer.

static OpaquePtr make(TemplateName 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.

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, bool IsNewScope, ImplicitTypenameContext AllowImplicitTypename)

Try to annotate a type or scope token, having already parsed an optional scope specifier.

SourceLocation ConsumeToken()

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

DeclGroupPtrTy ParseOpenACCDirectiveDecl()

Placeholder for now, should just ignore the directives after emitting a diagnostic.

Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)

void EnterScope(unsigned ScopeFlags)

EnterScope - Start a new scope.

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.

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

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

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

friend class ObjCDeclContextSwitch

void ExitScope()

ExitScope - Pop a scope off the scope stack.

const LangOptions & getLangOpts() const

bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result, Sema::ModuleImportState &ImportState)

Parse the first top-level declaration in a translation unit.

SkipUntilFlags

Control flags for SkipUntil functions.

@ StopBeforeMatch

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

@ StopAtCodeCompletion

Stop at code completion.

@ StopAtSemi

Stop skipping at semicolon.

bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)

TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...

bool MightBeCXXScopeToken()

ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)

const Token & NextToken()

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

SmallVector< TemplateParameterList *, 4 > TemplateParameterLists

void Initialize()

Initialize - Warm up the parser.

bool TryAnnotateCXXScopeToken(bool EnteringContext=false)

TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...

A class for parsing a DeclSpec.

A class for parsing a declarator.

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

void setCodeCompletionHandler(CodeCompletionHandler &Handler)

Set the code completion handler to the given object.

bool isIncrementalProcessingEnabled() const

Returns true if incremental processing is enabled.

void EnterToken(const Token &Tok, bool IsReinject)

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

void TypoCorrectToken(const Token &Tok)

Update the current token to represent the provided identifier, in order to cache an action performed ...

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.

void addCommentHandler(CommentHandler *Handler)

Add the specified comment handler to the preprocessor.

void removeCommentHandler(CommentHandler *Handler)

Remove the specified comment handler.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

SourceManager & getSourceManager() const

bool isBacktrackEnabled() const

True if EnableBacktrackAtThisPos() was called and caching of tokens is on.

void SetPoisonReason(IdentifierInfo *II, unsigned DiagID)

Specifies the reason for poisoning an identifier.

void RevertCachedTokens(unsigned N)

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

unsigned getTokenCount() const

Get the number of tokens processed so far.

unsigned getMaxTokens() const

Get the max number of tokens before issuing a -Wmax-tokens warning.

SourceLocation getMaxTokensOverrideLoc() const

bool hadModuleLoaderFatalFailure() const

StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const

Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...

bool isCodeCompletionEnabled() const

Determine if we are performing code completion.

IdentifierTable & getIdentifierTable()

void clearCodeCompletionHandler()

Clear out the code completion handler.

bool isCodeCompletionReached() const

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

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

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

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

Represents a struct/union/class.

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

void Init(Scope *parent, unsigned flags)

Init - This is used by the parser to implement scope caching.

const Scope * getParent() const

getParent - Return the scope that this is nested in.

@ FunctionPrototypeScope

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

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

ParserCompletionContext

Describes the context in which code completion occurs.

@ PCC_TopLevelOrExpression

Code completion occurs at top-level in a REPL session.

@ PCC_Class

Code completion occurs within a class, struct, or union.

@ PCC_ObjCImplementation

Code completion occurs within an Objective-C implementation or category implementation.

@ PCC_Namespace

Code completion occurs at top-level or namespace context.

@ PCC_RecoveryInFunction

Code completion occurs within the body of a function on a recovery path, where we do not have a speci...

void CodeCompletePreprocessorMacroName(bool IsDefinition)

void CodeCompleteInPreprocessorConditionalExclusion(Scope *S)

void CodeCompletePreprocessorExpression()

void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)

void CodeCompletePreprocessorMacroArgument(Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument)

void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path)

void CodeCompleteObjCMethodDecl(Scope *S, std::optional< bool > IsInstanceMethod, ParsedType ReturnType)

void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)

void CodeCompleteNaturalLanguage()

void CodeCompletePreprocessorDirective(bool InConditional)

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

ExprResult getExpression() const

NameClassificationKind getKind() const

NamedDecl * getNonTypeDecl() const

TemplateName getTemplateName() const

ParsedType getType() const

TemplateNameKind getTemplateNameKind() const

Sema - This implements semantic analysis and AST building for C.

void ActOnPopScope(SourceLocation Loc, Scope *S)

void ActOnDefinedDeclarationSpecifier(Decl *D)

Called once it is known whether a tag declaration is an anonymous union or struct.

Decl * ActOnSkippedFunctionBody(Decl *Decl)

void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod)

The parsed has entered a submodule.

void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod)

The parser has processed a module import translated from a #include or similar preprocessing directiv...

@ IER_DoesNotExist

The symbol does not exist.

@ IER_Dependent

The name is a dependent name, so the results will differ from one instantiation to the next.

@ IER_Error

An error occurred.

@ IER_Exists

The symbol exists.

Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})

ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...

void Initialize()

Perform initialization that occurs after the parser has been initialized but before it parses anythin...

@ Interface

'export module X;'

@ Implementation

'module X;'

void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind, StringLiteral *DeletedMessage=nullptr)

NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)

void ActOnComment(SourceRange Comment)

@ Other

C++26 [dcl.fct.def.general]p1 function-body: ctor-initializer[opt] compound-statement function-try-bl...

@ Delete

deleted-function-body

void ActOnEndOfTranslationUnit()

ActOnEndOfTranslationUnit - This is called at the very end of the translation unit when EOF is reache...

void ActOnTranslationUnitScope(Scope *S)

Scope actions.

DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, ModuleImportState &ImportState)

The parser has processed a module-declaration that begins the definition of a module interface or imp...

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

Decl * ActOnFileScopeAsmDecl(Expr *expr, SourceLocation AsmLoc, SourceLocation RParenLoc)

DeclarationNameInfo GetNameForDeclarator(Declarator &D)

GetNameForDeclarator - Determine the full declaration name for the given Declarator.

void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod)

The parser has left a submodule.

DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path, bool IsPartition=false)

The parser has processed a module import declaration.

DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)

ASTContext & getASTContext() const

@ NC_Unknown

This name is not a type or template in this context, but might be something else.

@ NC_VarTemplate

The name was classified as a variable template name.

@ NC_NonType

The name was classified as a specific non-type, non-template declaration.

@ NC_TypeTemplate

The name was classified as a template whose specializations are types.

@ NC_Error

Classification failed; an error has been produced.

@ NC_FunctionTemplate

The name was classified as a function template name.

@ NC_DependentNonType

The name denotes a member of a dependent type that could not be resolved.

@ NC_UndeclaredNonType

The name was classified as an ADL-only function name.

@ NC_UndeclaredTemplate

The name was classified as an ADL-only function template name.

@ NC_Keyword

The name has been typo-corrected to a keyword.

@ NC_Type

The name was classified as a type.

@ NC_OverloadSet

The name was classified as an overload set, and an expression representing that overload set has been...

@ NC_Concept

The name was classified as a concept name.

void PopExpressionEvaluationContext()

void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, CachedTokens &Toks)

void * SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS)

Given a C++ nested-name-specifier, produce an annotation value that the parser can use later to recon...

void SetLateTemplateParser(LateTemplateParserCB *LTP, LateTemplateParserCleanupCB *LTPCleanup, void *P)

SemaCodeCompletion & CodeCompletion()

ASTConsumer & getASTConsumer() const

Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)

bool canDelayFunctionBody(const Declarator &D)

Determine whether we can delay parsing the body of a function or function template until it is used,...

std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback

Callback to the parser to parse a type expressed as a string.

NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)

Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...

DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)

The parser has processed a global-module-fragment declaration that begins the definition of the globa...

DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)

BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...

void CheckForFunctionRedefinition(FunctionDecl *FD, const FunctionDecl *EffectiveDefinition=nullptr, SkipBodyInfo *SkipBody=nullptr)

IfExistsResult CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo)

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)

The parser has processed a private-module-fragment declaration that begins the definition of the priv...

bool canSkipFunctionBody(Decl *D)

Determine whether we can skip parsing the body of a function definition, assuming we don't care about...

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

void ActOnDefaultCtorInitializers(Decl *CDtorDecl)

TypeResult ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS, const IdentifierInfo &II, SourceLocation IdLoc, ImplicitTypenameContext IsImplicitTypename=ImplicitTypenameContext::No)

Called when the parser has parsed a C++ typename specifier, e.g., "typename T::type".

void ActOnStartOfTranslationUnit()

This is called before the very first declaration in the translation unit is parsed.

ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)

If the identifier refers to a type name within this scope, return the declaration of that type.

ModuleImportState

An enumeration to represent the transition of states in parsing module fragments and imports.

@ PrivateFragmentImportFinished

after 'module :private;' but a non-import decl has already been seen.

@ ImportFinished

after any non-import decl.

@ PrivateFragmentImportAllowed

after 'module :private;' but before any non-import decl.

@ FirstDecl

Parsing the first decl in a TU.

@ GlobalFragment

after 'module;' but before 'module X;'

@ NotACXX20Module

Not a C++20 TU, or an invalid state was found.

@ ImportAllowed

after 'module X;' but before any non-import decl.

Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)

ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....

void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls)

Decl * ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList, SourceLocation SemiLoc)

Handle a C++11 empty-declaration and attribute-declaration.

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.

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

StringLiteral - This represents a string literal expression, e.g.

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

bool isEditorPlaceholder() const

Returns true if this token is an editor placeholder.

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

void * getAnnotationValue() const

tok::TokenKind getKind() const

bool isAtStartOfLine() const

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

bool hasLeadingSpace() const

Return true if this token has whitespace before it.

SourceRange getAnnotationRange() const

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

void setLocation(SourceLocation L)

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)

bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const

Return true if we have an ObjC keyword identifier.

void setAnnotationRange(SourceRange R)

void startToken()

Reset all flags to cleared.

void setIdentifierInfo(IdentifierInfo *II)

SourceLocation getLastLoc() const

bool isObjCObjectType() const

bool isObjCObjectPointerType() const

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

TokenKind

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

const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE

Determines the spelling of simple punctuation tokens like '!' or '', and returns NULL for literal and...

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

TypeSpecifierType

Specifies the kind of type.

@ Self

'self' clause, allowed on Compute and Combined Constructs, plus 'update'.

bool isLambdaCallOperator(const CXXMethodDecl *MD)

@ Result

The result type of a method or function.

MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg

TemplateNameKind

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

@ TNK_Type_template

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

@ TNK_Undeclared_template

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

const FunctionProtoType * T

llvm::StringRef getAsString(SyncScope S)

@ Braces

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

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

ParamInfo * Params

Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...

unsigned NumParams

NumParams - This is the number of formal parameters specified by the declarator.

bool isKNRPrototype() const

isKNRPrototype - Return true if this is a K&R style identifier list, like "void foo(a,...

const IdentifierInfo * Ident

Wraps an identifier and optional source location for the identifier.

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

Information about a template-id annotation token.

const IdentifierInfo * Name

FIXME: Temporarily stores the name of a specialization.

TemplateNameKind Kind

The kind of template that Template refers to.

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.

bool mightBeType() const

Determine whether this might be a type template.

ParsedTemplateTy Template

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