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

1

2

3

4

5

6

7

8

9

10

11

12

26#include "llvm/ADT/STLForwardCompat.h"

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

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

29using namespace clang;

30

31

32namespace {

33

34

36 Sema &S;

37

38public:

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

40

41 bool HandleComment(Preprocessor &PP, SourceRange Comment) override {

42 S.ActOnComment(Comment);

43 return false;

44 }

45};

46}

47

49

51 Ident__except = PP.getIdentifierInfo("__except");

52

53 return Ident__except;

54}

55

57 : PP(pp),

58 PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),

59 Actions(actions), Diags(PP.getDiagnostics()), StackHandler(Diags),

60 GreaterThanIsOperator(true), ColonIsSacred(false),

61 InMessageExpression(false), ParsingInObjCContainer(false),

62 TemplateParameterDepth(0) {

64 Tok.startToken();

65 Tok.setKind(tok::eof);

66 Actions.CurScope = nullptr;

67 NumCachedScopes = 0;

68 CurParsedObjCImpl = nullptr;

69

70

71

72 initializePragmaHandlers();

73

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

75 PP.addCommentHandler(CommentSemaHandler.get());

76

77 PP.setCodeCompletionHandler(*this);

78

79 Actions.ParseTypeFromStringCallback =

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

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

82 };

83}

84

86 return Diags.Report(Loc, DiagID);

87}

88

90 return Diag(Tok.getLocation(), DiagID);

91}

92

94 unsigned CompatDiagId) {

95 return Diag(Loc,

97}

98

100 return DiagCompat(Tok.getLocation(), CompatDiagId);

101}

102

103void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,

107

108

109 Diag(Loc, DK);

110 return;

111 }

112

113 Diag(Loc, DK)

116}

117

119 switch (ExpectedTok) {

120 case tok:πŸš›

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

122 default: return false;

123 }

124}

125

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

127 StringRef Msg) {

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

130 return false;

131 }

132

133

135 SourceLocation Loc = Tok.getLocation();

136 {

137 DiagnosticBuilder DB = Diag(Loc, DiagID);

140 if (DiagID == diag::err_expected)

141 DB << ExpectedTok;

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

143 DB << Msg << ExpectedTok;

144 else

145 DB << Msg;

146 }

147

148

150 return false;

151 }

152

153 SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);

154 const char *Spelling = nullptr;

157

158 DiagnosticBuilder DB =

159 Spelling

161 : Diag(Tok, DiagID);

162 if (DiagID == diag::err_expected)

163 DB << ExpectedTok;

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

165 DB << Msg << ExpectedTok;

166 else

167 DB << Msg;

168

169 return true;

170}

171

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

174 return false;

175

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

177 handleUnexpectedCodeCompletionToken();

178 return false;

179 }

180

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

183 Diag(Tok, diag::err_extraneous_token_before_semi)

184 << PP.getSpelling(Tok)

188 return false;

189 }

190

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

192}

193

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

196

197 bool HadMultipleSemis = false;

198 SourceLocation StartLoc = Tok.getLocation();

199 SourceLocation EndLoc = Tok.getLocation();

201

202 while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) {

203 HadMultipleSemis = true;

204 EndLoc = Tok.getLocation();

206 }

207

208

209

212 Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)

214 else

215 Diag(StartLoc, diag::ext_extra_semi_cxx11)

217 return;

218 }

219

221 Diag(StartLoc, diag::ext_extra_semi)

224 TST, Actions.getASTContext().getPrintingPolicy())

226 else

227

228 Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)

230}

231

232bool Parser::expectIdentifier() {

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

234 return false;

235 if (const auto *II = Tok.getIdentifierInfo()) {

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

237 Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)

238 << tok::identifier << Tok.getIdentifierInfo();

239

240 return false;

241 }

242 }

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

244 return true;

245}

246

247void Parser::checkCompoundToken(SourceLocation FirstTokLoc,

250 return;

251 SourceLocation SecondTokLoc = Tok.getLocation();

252

253

254

256 PP.getSourceManager().getFileID(FirstTokLoc) !=

257 PP.getSourceManager().getFileID(SecondTokLoc)) {

258 Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro)

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

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

261 Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here)

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

263 << SourceRange(SecondTokLoc);

264 return;

265 }

266

267

268 if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {

269 SourceLocation SpaceLoc = PP.getLocForEndOfToken(FirstTokLoc);

271 SpaceLoc = FirstTokLoc;

272 Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace)

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

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

275 return;

276 }

277}

278

279

280

281

282

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

285}

286

288

289

290 bool isFirstTokenSkipped = true;

291 while (true) {

292

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

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

296

297 } else {

299 }

300 return true;

301 }

302 }

303

304

305

306

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

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

312 return true;

313 }

314

315 switch (Tok.getKind()) {

316 case tok::eof:

317

318 return false;

319

320 case tok::annot_pragma_openmp:

321 case tok::annot_attr_openmp:

322 case tok::annot_pragma_openmp_end:

323

324 if (OpenMPDirectiveParsing)

325 return false;

326 ConsumeAnnotationToken();

327 break;

328 case tok::annot_pragma_openacc:

329 case tok::annot_pragma_openacc_end:

330

331 if (OpenACCDirectiveParsing)

332 return false;

333 ConsumeAnnotationToken();

334 break;

335 case tok::annot_module_begin:

336 case tok::annot_module_end:

337 case tok::annot_module_include:

338 case tok::annot_repl_input_end:

339

340

341

342 return false;

343

344 case tok::code_completion:

346 handleUnexpectedCodeCompletionToken();

347 return false;

348

349 case tok::l_paren:

350

351 ConsumeParen();

354 else

356 break;

357 case tok::l_square:

358

359 ConsumeBracket();

362 else

364 break;

365 case tok::l_brace:

366

367 ConsumeBrace();

370 else

372 break;

373 case tok::question:

374

375

380 break;

381

382

383

384

385

386

387 case tok::r_paren:

388 if (ParenCount && !isFirstTokenSkipped)

389 return false;

390 ConsumeParen();

391 break;

392 case tok::r_square:

393 if (BracketCount && !isFirstTokenSkipped)

394 return false;

395 ConsumeBracket();

396 break;

397 case tok::r_brace:

398 if (BraceCount && !isFirstTokenSkipped)

399 return false;

400 ConsumeBrace();

401 break;

402

403 case tok:πŸš›

405 return false;

406 [[fallthrough]];

407 default:

408

410 break;

411 }

412 isFirstTokenSkipped = false;

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

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

432

433

434

435 Actions.ActOnPopScope(Tok.getLocation(), getCurScope());

436

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

439

440 if (NumCachedScopes == ScopeCacheSize)

441 delete OldScope;

442 else

443 ScopeCache[NumCachedScopes++] = OldScope;

444}

445

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

447 bool ManageFlags)

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

449 if (CurScope) {

450 OldFlags = CurScope->getFlags();

451 CurScope->setFlags(ScopeFlags);

452 }

453}

454

455Parser::ParseScopeFlags::~ParseScopeFlags() {

456 if (CurScope)

457 CurScope->setFlags(OldFlags);

458}

459

460

461

462

463

464

466

468 Actions.CurScope = nullptr;

469

470

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

472 delete ScopeCache[i];

473

474 resetPragmaHandlers();

475

476 PP.removeCommentHandler(CommentSemaHandler.get());

477

478 PP.clearCodeCompletionHandler();

479

480 DestroyTemplateIds();

481}

482

484

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

487 Actions.ActOnTranslationUnitScope(getCurScope());

488

489

490

493 &PP.getIdentifierTable().get("in");

495 &PP.getIdentifierTable().get("out");

497 &PP.getIdentifierTable().get("inout");

499 &PP.getIdentifierTable().get("oneway");

501 &PP.getIdentifierTable().get("bycopy");

503 &PP.getIdentifierTable().get("byref");

505 &PP.getIdentifierTable().get("nonnull");

507 &PP.getIdentifierTable().get("nullable");

509 &PP.getIdentifierTable().get("null_unspecified");

510 }

511

512 Ident_instancetype = nullptr;

513 Ident_final = nullptr;

514 Ident_sealed = nullptr;

515 Ident_abstract = nullptr;

516 Ident_override = nullptr;

517 Ident_trivially_relocatable_if_eligible = nullptr;

518 Ident_GNU_final = nullptr;

519 Ident_import = nullptr;

520 Ident_module = nullptr;

521

522 Ident_super = &PP.getIdentifierTable().get("super");

523

524 Ident_vector = nullptr;

525 Ident_bool = nullptr;

526 Ident_Bool = nullptr;

527 Ident_pixel = nullptr;

529 Ident_vector = &PP.getIdentifierTable().get("vector");

530 Ident_bool = &PP.getIdentifierTable().get("bool");

531 Ident_Bool = &PP.getIdentifierTable().get("_Bool");

532 }

534 Ident_pixel = &PP.getIdentifierTable().get("pixel");

535

536 Ident_introduced = nullptr;

537 Ident_deprecated = nullptr;

538 Ident_obsoleted = nullptr;

539 Ident_unavailable = nullptr;

540 Ident_strict = nullptr;

541 Ident_replacement = nullptr;

542

543 Ident_language = Ident_defined_in = Ident_generated_declaration = Ident_USR =

544 nullptr;

545

546 Ident__except = nullptr;

547

548 Ident__exception_code = Ident__exception_info = nullptr;

549 Ident__abnormal_termination = Ident___exception_code = nullptr;

550 Ident___exception_info = Ident___abnormal_termination = nullptr;

551 Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;

552 Ident_AbnormalTermination = nullptr;

553

555 Ident__exception_info = PP.getIdentifierInfo("_exception_info");

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

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

558 Ident__exception_code = PP.getIdentifierInfo("_exception_code");

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

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

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

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

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

564

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

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

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

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

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

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

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

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

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

574 }

575

577 Ident_import = PP.getIdentifierInfo("import");

578 Ident_module = PP.getIdentifierInfo("module");

579 }

580

581 Actions.Initialize();

582

583

585}

586

587void Parser::DestroyTemplateIds() {

589 Id->Destroy();

590 TemplateIds.clear();

591}

592

595 Actions.ActOnStartOfTranslationUnit();

596

597

598

601

602

603

604

605

606

607 if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&

609 Diag(diag::ext_empty_translation_unit);

610

611 return NoTopLevelDecls;

612}

613

616 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);

617

619 switch (Tok.getKind()) {

620 case tok::annot_pragma_unused:

621 HandlePragmaUnused();

622 return false;

623

624 case tok::kw_export:

626 case tok::kw_module:

627 goto module_decl;

628

629

630

631

632

633

634

635 case tok::identifier: {

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

639 if (II == Ident_module)

640 goto module_decl;

641 else

642 goto import_decl;

643 }

644 break;

645 }

646

647 default:

648 break;

649 }

650 break;

651

652 case tok::kw_module:

653 module_decl:

654 Result = ParseModuleDecl(ImportState);

655 return false;

656

657 case tok::kw_import:

658 import_decl: {

661 return false;

662 }

663

664 case tok::annot_module_include: {

665 auto Loc = Tok.getLocation();

666 Module *Mod = reinterpret_cast<Module *>(Tok.getAnnotationValue());

667

668

670 Actions.ActOnAnnotModuleInclude(Loc, Mod);

671 else {

673 Actions.ActOnModuleImport(Loc, SourceLocation(), Loc, Mod);

676 }

677 ConsumeAnnotationToken();

678 return false;

679 }

680

681 case tok::annot_module_begin:

682 Actions.ActOnAnnotModuleBegin(

683 Tok.getLocation(),

684 reinterpret_cast<Module *>(Tok.getAnnotationValue()));

685 ConsumeAnnotationToken();

687 return false;

688

689 case tok::annot_module_end:

690 Actions.ActOnAnnotModuleEnd(

691 Tok.getLocation(),

692 reinterpret_cast<Module *>(Tok.getAnnotationValue()));

693 ConsumeAnnotationToken();

695 return false;

696

697 case tok::eof:

698 case tok::annot_repl_input_end:

699

700 if (PP.getMaxTokens() != 0 && PP.getTokenCount() > PP.getMaxTokens()) {

701 PP.Diag(Tok.getLocation(), diag::warn_max_tokens_total)

702 << PP.getTokenCount() << PP.getMaxTokens();

703 SourceLocation OverrideLoc = PP.getMaxTokensOverrideLoc();

704 if (OverrideLoc.isValid()) {

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

706 }

707 }

708

709

710 Actions.SetLateTemplateParser(LateTemplateParserCallback, this);

711 Actions.ActOnEndOfTranslationUnit();

712

713 return true;

714

715 case tok::identifier:

716

717

718

719

720 if ((Tok.getIdentifierInfo() == Ident_module ||

721 Tok.getIdentifierInfo() == Ident_import) &&

723 if (Tok.getIdentifierInfo() == Ident_module)

724 goto module_decl;

725 else

726 goto import_decl;

727 }

728 break;

729

730 default:

731 break;

732 }

733

736

737

738

739

740 while (MaybeParseCXX11Attributes(DeclAttrs) ||

741 MaybeParseGNUAttributes(DeclSpecAttrs))

742 ;

743

744 Result = ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);

745

746

749

752

754 else if (ImportState ==

756

758 }

759 return false;

760}

761

766 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);

768

770 cutOffParsing();

771 return nullptr;

772 }

773

774 Decl *SingleDecl = nullptr;

775 switch (Tok.getKind()) {

776 case tok::annot_pragma_vis:

777 HandlePragmaVisibility();

778 return nullptr;

779 case tok::annot_pragma_pack:

780 HandlePragmaPack();

781 return nullptr;

782 case tok::annot_pragma_msstruct:

783 HandlePragmaMSStruct();

784 return nullptr;

785 case tok::annot_pragma_align:

786 HandlePragmaAlign();

787 return nullptr;

788 case tok::annot_pragma_weak:

789 HandlePragmaWeak();

790 return nullptr;

791 case tok::annot_pragma_weakalias:

792 HandlePragmaWeakAlias();

793 return nullptr;

794 case tok::annot_pragma_redefine_extname:

795 HandlePragmaRedefineExtname();

796 return nullptr;

797 case tok::annot_pragma_fp_contract:

798 HandlePragmaFPContract();

799 return nullptr;

800 case tok::annot_pragma_fenv_access:

801 case tok::annot_pragma_fenv_access_ms:

802 HandlePragmaFEnvAccess();

803 return nullptr;

804 case tok::annot_pragma_fenv_round:

805 HandlePragmaFEnvRound();

806 return nullptr;

807 case tok::annot_pragma_cx_limited_range:

808 HandlePragmaCXLimitedRange();

809 return nullptr;

810 case tok::annot_pragma_float_control:

811 HandlePragmaFloatControl();

812 return nullptr;

813 case tok::annot_pragma_fp:

814 HandlePragmaFP();

815 break;

816 case tok::annot_pragma_opencl_extension:

817 HandlePragmaOpenCLExtension();

818 return nullptr;

819 case tok::annot_attr_openmp:

820 case tok::annot_pragma_openmp: {

822 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);

823 }

824 case tok::annot_pragma_openacc: {

827 nullptr);

828 }

829 case tok::annot_pragma_ms_pointers_to_members:

830 HandlePragmaMSPointersToMembers();

831 return nullptr;

832 case tok::annot_pragma_ms_vtordisp:

833 HandlePragmaMSVtorDisp();

834 return nullptr;

835 case tok::annot_pragma_ms_pragma:

836 HandlePragmaMSPragma();

837 return nullptr;

838 case tok::annot_pragma_dump:

839 HandlePragmaDump();

840 return nullptr;

841 case tok::annot_pragma_attribute:

842 HandlePragmaAttribute();

843 return nullptr;

844 case tok:πŸš›

845

846 SingleDecl =

847 Actions.ActOnEmptyDeclaration(getCurScope(), Attrs, Tok.getLocation());

849 break;

850 case tok::r_brace:

851 Diag(Tok, diag::err_extraneous_closing_brace);

852 ConsumeBrace();

853 return nullptr;

854 case tok::eof:

855 Diag(Tok, diag::err_expected_external_declaration);

856 return nullptr;

857 case tok::kw___extension__: {

858

859 ExtensionRAIIObject O(Diags);

861 return ParseExternalDeclaration(Attrs, DeclSpecAttrs);

862 }

863 case tok::kw_asm: {

864 ProhibitAttributes(Attrs);

865

866 SourceLocation StartLoc = Tok.getLocation();

867 SourceLocation EndLoc;

868

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

870

871

872

873

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

877 Diag(StartLoc, diag::err_gnu_inline_asm_disabled);

878 }

879

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

881 "top-level asm block");

882

883 if (Result.isInvalid())

884 return nullptr;

885 SingleDecl = Actions.ActOnFileScopeAsmDecl(Result.get(), StartLoc, EndLoc);

886 break;

887 }

888 case tok::at:

889 return ParseObjCAtDirectives(Attrs, DeclSpecAttrs);

890 case tok:βž–

891 case tok:βž•

893 Diag(Tok, diag::err_expected_external_declaration);

895 return nullptr;

896 }

897 SingleDecl = ParseObjCMethodDefinition();

898 break;

899 case tok::code_completion:

900 cutOffParsing();

901 if (CurParsedObjCImpl) {

902

903 Actions.CodeCompletion().CodeCompleteObjCMethodDecl(

905 std::nullopt,

906 nullptr);

907 }

908

910 if (CurParsedObjCImpl) {

912 } else if (PP.isIncrementalProcessingEnabled()) {

914 } else {

916 };

917 Actions.CodeCompletion().CodeCompleteOrdinaryName(getCurScope(), PCC);

918 return nullptr;

919 case tok::kw_import: {

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

923 ProhibitAttributes(Attrs);

924 }

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

926 } break;

927 case tok::kw_export:

929 ProhibitAttributes(Attrs);

930 SingleDecl = ParseExportDeclaration();

931 break;

932 }

933

934

935 [[fallthrough]];

936 case tok::kw_using:

937 case tok::kw_namespace:

938 case tok::kw_typedef:

939 case tok::kw_template:

940 case tok::kw_static_assert:

941 case tok::kw__Static_assert:

942

943 {

944 SourceLocation DeclEnd;

946 DeclSpecAttrs);

947 }

948

949 case tok::kw_cbuffer:

950 case tok::kw_tbuffer:

952 SourceLocation DeclEnd;

954 DeclSpecAttrs);

955 }

956 goto dont_know;

957

958 case tok::kw_static:

959

960

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

963 << 0;

964 SourceLocation DeclEnd;

966 DeclSpecAttrs);

967 }

968 goto dont_know;

969

970 case tok::kw_inline:

973

974

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

976 SourceLocation DeclEnd;

978 DeclSpecAttrs);

979 }

980

981

982

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

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

985 << 1;

986 SourceLocation DeclEnd;

988 DeclSpecAttrs);

989 }

990 }

991 goto dont_know;

992

993 case tok::kw_extern:

995 ProhibitAttributes(Attrs);

996 ProhibitAttributes(DeclSpecAttrs);

997

1001 diag::warn_cxx98_compat_extern_template :

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

1003 SourceLocation DeclEnd;

1005 TemplateLoc, DeclEnd, Attrs);

1006 }

1007 goto dont_know;

1008

1009 case tok::kw___if_exists:

1010 case tok::kw___if_not_exists:

1011 ParseMicrosoftIfExistsExternalDeclaration();

1012 return nullptr;

1013

1014 case tok::kw_module:

1015 Diag(Tok, diag::err_unexpected_module_decl);

1017 return nullptr;

1018

1019 default:

1020 dont_know:

1021 if (Tok.isEditorPlaceholder()) {

1023 return nullptr;

1024 }

1025 if (getLangOpts().IncrementalExtensions &&

1026 !isDeclarationStatement(true))

1027 return ParseTopLevelStmtDecl();

1028

1029

1030 if (!SingleDecl)

1031 return ParseDeclarationOrFunctionDefinition(Attrs, DeclSpecAttrs, DS);

1032 }

1033

1034

1035

1036 return Actions.ConvertDeclToDeclGroup(SingleDecl);

1037}

1038

1039bool Parser::isDeclarationAfterDeclarator() {

1040

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

1044 return false;

1045 }

1046

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

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

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

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

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

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

1054}

1055

1056bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {

1057 assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");

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

1059 return true;

1060

1061

1063 Declarator.getFunctionTypeInfo().isKNRPrototype())

1065

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

1069 }

1070

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

1072 Tok.is(tok::kw_try);

1073}

1074

1076 ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,

1078

1079

1080

1082 "expected uninitialised source range");

1086

1087 ParsedTemplateInfo TemplateInfo;

1088 MaybeParseMicrosoftAttributes(DS.getAttributes());

1089

1090 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,

1091 DeclSpecContext::DSC_top_level);

1092

1093

1094

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

1096 DS, AS, DeclSpecContext::DSC_top_level))

1097 return nullptr;

1098

1099

1100

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

1102

1103

1104 SourceLocation CorrectLocationForAttributes{};

1108 if (const auto *ED = dyn_cast_or_null(DS.getRepAsDecl())) {

1109 CorrectLocationForAttributes =

1110 PP.getLocForEndOfToken(ED->getEnumKeyRange().getEnd());

1111 }

1112 }

1113 if (CorrectLocationForAttributes.isInvalid()) {

1114 const auto &Policy = Actions.getASTContext().getPrintingPolicy();

1115 unsigned Offset =

1117 CorrectLocationForAttributes =

1119 }

1120 }

1121 ProhibitAttributes(Attrs, CorrectLocationForAttributes);

1123 RecordDecl *AnonRecord = nullptr;

1124 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(

1127 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);

1128 if (AnonRecord) {

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

1130 return Actions.BuildDeclaratorGroup(decls);

1131 }

1132 return Actions.ConvertDeclToDeclGroup(TheDecl);

1133 }

1134

1136 Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());

1137

1138

1139

1140

1142 SourceLocation AtLoc = ConsumeToken();

1143 if (!Tok.isObjCAtKeyword(tok::objc_interface) &&

1144 !Tok.isObjCAtKeyword(tok::objc_protocol) &&

1145 !Tok.isObjCAtKeyword(tok::objc_implementation)) {

1146 Diag(Tok, diag::err_objc_unexpected_attr);

1148 return nullptr;

1149 }

1150

1153

1154 const char *PrevSpec = nullptr;

1155 unsigned DiagID;

1157 Actions.getASTContext().getPrintingPolicy()))

1158 Diag(AtLoc, DiagID) << PrevSpec;

1159

1160 if (Tok.isObjCAtKeyword(tok::objc_protocol))

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

1162

1163 if (Tok.isObjCAtKeyword(tok::objc_implementation))

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

1165

1166 return Actions.ConvertDeclToDeclGroup(

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

1168 }

1169

1170

1171

1172

1176 ProhibitAttributes(Attrs);

1178 return Actions.ConvertDeclToDeclGroup(TheDecl);

1179 }

1180

1182}

1183

1185 ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,

1187

1188

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

1190 return Tok.getLocation().printToString(

1191 Actions.getASTContext().getSourceManager());

1192 });

1193

1194 if (DS) {

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

1196 } else {

1197 ParsingDeclSpec PDS(*this);

1198

1199

1200

1201 ObjCDeclContextSwitch ObjCDC(*this);

1202

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

1204 }

1205}

1206

1207Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,

1208 const ParsedTemplateInfo &TemplateInfo,

1209 LateParsedAttrList *LateParsedAttrs) {

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

1211 return Actions.GetNameForDeclarator(D).getName().getAsString();

1212 });

1213

1214

1217 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);

1218

1219

1220

1221

1225 const char *PrevSpec;

1226 unsigned DiagID;

1227 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();

1230 PrevSpec, DiagID,

1231 Policy);

1233 }

1234

1235

1236

1237

1239 ParseKNRParamDeclarations(D);

1240

1241

1242

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

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

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

1247 Diag(Tok, diag::err_expected_fn_body);

1248

1249

1251

1252

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

1254 return nullptr;

1255 }

1256

1257

1258

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

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

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

1263 }

1264

1265

1266

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

1269 LateParsedAttrs->empty() && Actions.canDelayFunctionBody(D)) {

1271

1275

1277 Decl *DP = Actions.HandleDeclarator(ParentScope, D,

1281

1282 if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) &&

1283 trySkippingFunctionBody()) {

1284 BodyScope.Exit();

1285 return Actions.ActOnSkippedFunctionBody(DP);

1286 }

1287

1289 LexTemplateFunctionForLateParsing(Toks);

1290

1291 if (DP) {

1293 Actions.CheckForFunctionRedefinition(FnD);

1294 Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);

1295 }

1296 return DP;

1297 }

1298 if (CurParsedObjCImpl && !TemplateInfo.TemplateParams &&

1299 (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || Tok.is(tok::colon)) &&

1300 Actions.CurContext->isTranslationUnit()) {

1304

1306 Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,

1310 if (FuncDecl) {

1311

1312 StashAwayMethodOrFunctionBodyTokens(FuncDecl);

1313 CurParsedObjCImpl->HasCFunction = true;

1314 return FuncDecl;

1315 }

1316

1317 }

1318

1319

1322

1323

1324

1325 StringLiteral *DeletedMessage = nullptr;

1327 SourceLocation KWLoc;

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

1330

1333 ? diag::warn_cxx98_compat_defaulted_deleted_function

1334 : diag::ext_defaulted_deleted_function)

1335 << 1 ;

1337 DeletedMessage = ParseCXXDeletedFunctionMessage();

1340 ? diag::warn_cxx98_compat_defaulted_deleted_function

1341 : diag::ext_defaulted_deleted_function)

1342 << 0 ;

1344 } else {

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

1346 }

1347

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

1349 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)

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

1354 ? "delete"

1355 : "default")) {

1357 }

1358 }

1359

1360 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);

1361

1362

1363

1364 SkipBodyInfo SkipBody;

1365 Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,

1366 TemplateInfo.TemplateParams

1367 ? *TemplateInfo.TemplateParams

1369 &SkipBody, BodyKind);

1370

1372

1374 SkipFunctionBody();

1375

1376

1377

1378

1379

1380

1381

1382

1383

1384

1386 Actions.PopExpressionEvaluationContext();

1387 return Res;

1388 }

1389

1390

1392

1393

1394

1396

1398 Actions.SetFunctionBodyKind(Res, KWLoc, BodyKind, DeletedMessage);

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

1400 Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false);

1401 return Res;

1402 }

1403

1404

1405

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

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

1409

1410

1411 CurTemplateDepthTracker.addDepth(1);

1412

1413

1414 if (LateParsedAttrs)

1415 ParseLexedAttributeList(*LateParsedAttrs, Res, false,

1416 true);

1417

1418 if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&

1419 trySkippingFunctionBody()) {

1420 BodyScope.Exit();

1421 Actions.ActOnSkippedFunctionBody(Res);

1422 return Actions.ActOnFinishFunctionBody(Res, nullptr, false);

1423 }

1424

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

1426 return ParseFunctionTryBlock(Res, BodyScope);

1427

1428

1429

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

1431 ParseConstructorInitializer(Res);

1432

1433

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

1435 BodyScope.Exit();

1436 Actions.ActOnFinishFunctionBody(Res, nullptr);

1437 return Res;

1438 }

1439 } else

1440 Actions.ActOnDefaultCtorInitializers(Res);

1441

1442 return ParseFunctionStatementBody(Res, BodyScope);

1443}

1444

1445void Parser::SkipFunctionBody() {

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

1448 return;

1449 }

1450

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

1452 if (IsFunctionTryBlock)

1454

1456 if (ConsumeAndStoreFunctionPrologue(Skipped))

1458 else {

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

1463 }

1464 }

1465}

1466

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

1468

1470

1471

1472

1475

1476

1478 SourceLocation DSStart = Tok.getLocation();

1479

1480

1481 DeclSpec DS(AttrFactory);

1482 ParsedTemplateInfo TemplateInfo;

1483 ParseDeclarationSpecifiers(DS, TemplateInfo);

1484

1485

1486

1487

1488

1489

1491 Diag(DSStart, diag::err_declaration_does_not_declare_param);

1492 continue;

1493 }

1494

1495

1496

1500 diag::err_invalid_storage_class_in_func_decl);

1502 }

1505 diag::err_invalid_storage_class_in_func_decl);

1507 }

1508

1509

1512 ParseDeclarator(ParmDeclarator);

1513

1514

1515 while (true) {

1516

1517 MaybeParseGNUAttributes(ParmDeclarator);

1518

1519

1520 Decl *Param =

1521 Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);

1522

1523 if (Param &&

1524

1525 ParmDeclarator.getIdentifier()) {

1526

1527

1528

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

1530

1531

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

1534 << ParmDeclarator.getIdentifier();

1535 break;

1536 }

1537

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

1539

1541 Diag(ParmDeclarator.getIdentifierLoc(),

1542 diag::err_param_redefinition)

1543 << ParmDeclarator.getIdentifier();

1544 } else {

1546 }

1547 break;

1548 }

1549 }

1550 }

1551

1552

1553

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

1555 break;

1556

1557 ParmDeclarator.clear();

1558

1559

1561

1562

1563 ParseDeclarator(ParmDeclarator);

1564 }

1565

1566

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

1568 continue;

1569

1570

1572 break;

1574 }

1575

1576

1577 Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation());

1578}

1579

1580ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {

1581

1583 if (isTokenStringLiteral()) {

1586 return AsmString;

1587

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

1590 Diag(Tok, diag::err_asm_operand_wide_string_literal)

1591 << SL->isWide() << SL->getSourceRange();

1593 }

1595 Tok.is(tok::l_paren)) {

1597 SourceLocation RParenLoc;

1599

1600 EnterExpressionEvaluationContext ConstantEvaluated(

1602 AsmString = ParseParenExpression(

1606 AsmString = Actions.ActOnConstantExpression(AsmString);

1607

1610 } else {

1611 Diag(Tok, diag::err_asm_expected_string) << (

1612 (getLangOpts().CPlusPlus11 && !ForAsmLabel) ? 0 : 1);

1613 }

1614

1615 return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel);

1616}

1617

1618ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {

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

1621

1622 if (isGNUAsmQualifier(Tok)) {

1623

1624 SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),

1625 PP.getLocForEndOfToken(Tok.getLocation()));

1626 Diag(Tok, diag::err_global_asm_qualifier_ignored)

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

1630 }

1631

1633 if (T.consumeOpen()) {

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

1636 }

1637

1639

1640 if (Result.isInvalid()) {

1641

1642 T.consumeClose();

1643 if (EndLoc)

1644 *EndLoc = T.getCloseLocation();

1646 if (EndLoc)

1647 *EndLoc = Tok.getLocation();

1648 ConsumeParen();

1649 }

1650

1652}

1653

1654TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {

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

1656 TemplateIdAnnotation *

1658 return Id;

1659}

1660

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

1662

1663

1664 if (PP.isBacktrackEnabled())

1665 PP.RevertCachedTokens(1);

1666 else

1667 PP.EnterToken(Tok, true);

1668 Tok.setKind(tok::annot_cxxscope);

1669 Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));

1670 Tok.setAnnotationRange(SS.getRange());

1671

1672

1673

1674

1675 if (IsNewAnnotation)

1676 PP.AnnotateCachedTokens(Tok);

1677}

1678

1680Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,

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

1683

1684 const bool EnteringContext = false;

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

1686

1687 CXXScopeSpec SS;

1689 ParseOptionalCXXScopeSpecifier(SS, nullptr,

1690 false,

1691 EnteringContext))

1693

1694 if (Tok.isNot(tok::identifier) || SS.isInvalid()) {

1696 AllowImplicitTypename))

1699 }

1700

1701 IdentifierInfo *Name = Tok.getIdentifierInfo();

1702 SourceLocation NameLoc = Tok.getLocation();

1703

1704

1705

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

1707

1708

1710 AllowImplicitTypename))

1714 }

1715

1717

1718

1719

1720

1721

1722 Sema::NameClassification Classification = Actions.ClassifyName(

1724

1725

1726

1727

1728

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

1731

1732 Token FakeNext = Next;

1733 FakeNext.setKind(tok::unknown);

1734 Classification =

1735 Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, FakeNext,

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

1737 }

1738

1739 switch (Classification.getKind()) {

1742

1744

1745 Tok.setIdentifierInfo(Name);

1747 PP.TypoCorrectToken(Tok);

1749 AnnotateScopeToken(SS, !WasScopeAnnotation);

1750

1752

1754

1755 break;

1756

1758 if (TryAltiVecVectorToken())

1759

1760

1761

1762 break;

1763 SourceLocation BeginLoc = NameLoc;

1766

1767

1768

1770 QualType T = Actions.GetTypeFromParser(Ty);

1773

1774 SourceLocation IdentifierLoc = ConsumeToken();

1775 SourceLocation NewEndLoc;

1777 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,

1778 false,

1779 NewEndLoc);

1781 Ty = NewType.get();

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

1784 }

1785

1786 Tok.setKind(tok::annot_typename);

1787 setTypeAnnotation(Tok, Ty);

1788 Tok.setAnnotationEndLoc(Tok.getLocation());

1789 Tok.setLocation(BeginLoc);

1790 PP.AnnotateCachedTokens(Tok);

1792 }

1793

1795 Tok.setKind(tok::annot_overload_set);

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

1797 Tok.setAnnotationEndLoc(NameLoc);

1800 PP.AnnotateCachedTokens(Tok);

1802

1804 if (TryAltiVecVectorToken())

1805

1806

1807

1808 break;

1809 Tok.setKind(tok::annot_non_type);

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

1811 Tok.setLocation(NameLoc);

1812 Tok.setAnnotationEndLoc(NameLoc);

1813 PP.AnnotateCachedTokens(Tok);

1815 AnnotateScopeToken(SS, !WasScopeAnnotation);

1817

1820 Tok.setKind(Classification.getKind() ==

1822 ? tok::annot_non_type_undeclared

1823 : tok::annot_non_type_dependent);

1824 setIdentifierAnnotation(Tok, Name);

1825 Tok.setLocation(NameLoc);

1826 Tok.setAnnotationEndLoc(NameLoc);

1827 PP.AnnotateCachedTokens(Tok);

1829 AnnotateScopeToken(SS, !WasScopeAnnotation);

1831

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

1834

1835

1837 AnnotateScopeToken(SS, !WasScopeAnnotation);

1839 }

1840 [[fallthrough]];

1845 bool IsConceptName =

1847

1848

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

1853 if (AnnotateTemplateIdToken(

1856 !IsConceptName,

1857 IsConceptName))

1860 AnnotateScopeToken(SS, !WasScopeAnnotation);

1862 }

1863 }

1864

1865

1867 AnnotateScopeToken(SS, !WasScopeAnnotation);

1869}

1870

1872 SourceLocation TokenEndLoc = PP.getLocForEndOfToken(PrevTokLocation);

1873 return TokenEndLoc.isValid() ? TokenEndLoc : Tok.getLocation();

1874}

1875

1876bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {

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

1878 Diag(Tok, diag::ext_keyword_as_ident)

1880 << DisableKeyword;

1881 if (DisableKeyword)

1882 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();

1883 Tok.setKind(tok::identifier);

1884 return true;

1885}

1886

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

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

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

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

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

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

1895

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

1897

1898

1899

1900

1901

1902

1904 Token TypedefToken;

1905 PP.Lex(TypedefToken);

1907 PP.EnterToken(Tok, true);

1908 Tok = TypedefToken;

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

1912 }

1913

1914

1915

1916

1917

1918

1919

1922 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

1923 false,

1924 false, nullptr,

1925 true))

1926 return true;

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

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

1930

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

1933 Tok.isAnnotation())) {

1934 unsigned DiagID = diag::err_expected_qualified_after_typename;

1935

1936

1938 DiagID = diag::warn_expected_qualified_after_typename;

1939 Diag(Tok.getLocation(), DiagID);

1940 return false;

1941 }

1942 }

1943 if (Tok.isEditorPlaceholder())

1944 return true;

1945

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

1947 return true;

1948 }

1949

1950 bool TemplateKWPresent = false;

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

1953 TemplateKWPresent = true;

1954 }

1955

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

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

1959 Diag(Tok.getLocation(),

1960 diag::missing_template_arg_list_after_template_kw);

1961 return true;

1962 }

1963 Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,

1964 *Tok.getIdentifierInfo(),

1965 Tok.getLocation());

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

1969 Diag(Tok, diag::err_typename_refers_to_non_type_template)

1970 << Tok.getAnnotationRange();

1971 return true;

1972 }

1973

1976

1979 : Actions.ActOnTypenameType(

1983 TemplateArgsPtr, TemplateId->RAngleLoc);

1984 } else {

1985 Diag(Tok, diag::err_expected_type_name_after_typename)

1987 return true;

1988 }

1989

1991 Tok.setKind(tok::annot_typename);

1992 setTypeAnnotation(Tok, Ty);

1993 Tok.setAnnotationEndLoc(EndLoc);

1994 Tok.setLocation(TypenameLoc);

1995 PP.AnnotateCachedTokens(Tok);

1996 return false;

1997 }

1998

1999

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

2001

2004 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

2005 false,

2006 false))

2007 return true;

2008

2010 AllowImplicitTypename);

2011}

2012

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

2017

2018 if (ParsedType Ty = Actions.getTypeName(

2019 *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,

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

2021 false,

2022 true,

2023 true, AllowImplicitTypename)) {

2025 if (SS.isNotEmpty())

2027

2028 QualType T = Actions.GetTypeFromParser(Ty);

2029

2030

2031

2033 (T->isObjCObjectType() || T->isObjCObjectPointerType())) {

2034

2038 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,

2039 false,

2040 NewEndLoc);

2042 Ty = NewType.get();

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

2044 return false;

2045 }

2046

2047

2048

2049 Tok.setKind(tok::annot_typename);

2050 setTypeAnnotation(Tok, Ty);

2051 Tok.setAnnotationEndLoc(Tok.getLocation());

2052 Tok.setLocation(BeginLoc);

2053

2054

2055

2056 PP.AnnotateCachedTokens(Tok);

2057 return false;

2058 }

2059

2061

2062

2063

2064 return false;

2065 }

2066

2067

2068

2069

2073 TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());

2074 bool MemberOfUnknownSpecialization;

2078 nullptr, false, Template,

2079 MemberOfUnknownSpecialization)) {

2080

2081

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

2084

2088

2089

2090

2091 return true;

2092 }

2093 }

2094 }

2095 }

2096

2097

2098

2099

2100

2101 }

2102

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

2106

2107

2108

2109

2110 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);

2111 return false;

2112 }

2113 }

2114

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

2118

2120 return true;

2121 }

2122 return false;

2123 }

2124

2125

2126 AnnotateScopeToken(SS, IsNewScope);

2127 return false;

2128}

2129

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

2134

2136 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

2137 false,

2138 EnteringContext))

2139 return true;

2141 return false;

2142

2143 AnnotateScopeToken(SS, true);

2144 return false;

2145}

2146

2147bool Parser::isTokenEqualOrEqualTypo() {

2149 switch (Kind) {

2150 default:

2151 return false;

2152 case tok::ampequal:

2153 case tok::starequal:

2154 case tok::plusequal:

2155 case tok::minusequal:

2156 case tok::exclaimequal:

2157 case tok::slashequal:

2158 case tok::percentequal:

2159 case tok::lessequal:

2160 case tok::lesslessequal:

2161 case tok::greaterequal:

2162 case tok::greatergreaterequal:

2163 case tok::caretequal:

2164 case tok::pipeequal:

2165 case tok::equalequal:

2166 Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)

2167 << Kind

2169 [[fallthrough]];

2170 case tok::equal:

2171 return true;

2172 }

2173}

2174

2175SourceLocation Parser::handleUnexpectedCodeCompletionToken() {

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

2177 PrevTokLocation = Tok.getLocation();

2178

2180 if (S->isFunctionScope()) {

2181 cutOffParsing();

2182 Actions.CodeCompletion().CodeCompleteOrdinaryName(

2184 return PrevTokLocation;

2185 }

2186

2187 if (S->isClassScope()) {

2188 cutOffParsing();

2189 Actions.CodeCompletion().CodeCompleteOrdinaryName(

2191 return PrevTokLocation;

2192 }

2193 }

2194

2195 cutOffParsing();

2196 Actions.CodeCompletion().CodeCompleteOrdinaryName(

2198 return PrevTokLocation;

2199}

2200

2201

2202

2203void Parser::CodeCompleteDirective(bool InConditional) {

2204 Actions.CodeCompletion().CodeCompletePreprocessorDirective(InConditional);

2205}

2206

2208 Actions.CodeCompletion().CodeCompleteInPreprocessorConditionalExclusion(

2210}

2211

2212void Parser::CodeCompleteMacroName(bool IsDefinition) {

2213 Actions.CodeCompletion().CodeCompletePreprocessorMacroName(IsDefinition);

2214}

2215

2217 Actions.CodeCompletion().CodeCompletePreprocessorExpression();

2218}

2219

2220void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,

2221 MacroInfo *MacroInfo,

2222 unsigned ArgumentIndex) {

2223 Actions.CodeCompletion().CodeCompletePreprocessorMacroArgument(

2225}

2226

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

2228 Actions.CodeCompletion().CodeCompleteIncludedFile(Dir, IsAngled);

2229}

2230

2232 Actions.CodeCompletion().CodeCompleteNaturalLanguage();

2233}

2234

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

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

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

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

2240

2242 if (T.consumeOpen()) {

2243 Diag(Tok, diag::err_expected_lparen_after)

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

2245 return true;

2246 }

2247

2248

2250 ParseOptionalCXXScopeSpecifier(Result.SS, nullptr,

2251 false,

2252 false);

2253

2254

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

2256 T.skipToEnd();

2257 return true;

2258 }

2259

2260

2261 SourceLocation TemplateKWLoc;

2263 false, false,

2264 true,

2265 true,

2266 false, &TemplateKWLoc,

2268 T.skipToEnd();

2269 return true;

2270 }

2271

2272 if (T.consumeClose())

2273 return true;

2274

2275

2276 switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc,

2282 break;

2283

2287 break;

2288

2291 break;

2292

2294 return true;

2295 }

2296

2297 return false;

2298}

2299

2300void Parser::ParseMicrosoftIfExistsExternalDeclaration() {

2301 IfExistsCondition Result;

2302 if (ParseMicrosoftIfExistsCondition(Result))

2303 return;

2304

2306 if (Braces.consumeOpen()) {

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

2308 return;

2309 }

2310

2311 switch (Result.Behavior) {

2313

2314 break;

2315

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

2318

2321 return;

2322 }

2323

2324

2325

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

2327 ParsedAttributes Attrs(AttrFactory);

2328 MaybeParseCXX11Attributes(Attrs);

2329 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);

2330 DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs);

2332 Actions.getASTConsumer().HandleTopLevelDecl(Result.get());

2333 }

2334 Braces.consumeClose();

2335}

2336

2339 Token Introducer = Tok;

2340 SourceLocation StartLoc = Introducer.getLocation();

2341

2345

2346 assert(

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

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

2349 "not a module declaration");

2351

2352

2353

2354 DiagnoseAndSkipCXX11Attributes();

2355

2356

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

2361 Diag(StartLoc, diag::err_global_module_introducer_not_at_start)

2362 << SourceRange(StartLoc, SemiLoc);

2363 return nullptr;

2364 }

2366 Diag(StartLoc, diag::err_module_fragment_exported)

2368 }

2370 return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc);

2371 }

2372

2373

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

2377 Diag(StartLoc, diag::err_module_fragment_exported)

2379 }

2382 DiagnoseAndSkipCXX11Attributes();

2383 ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);

2387 return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc);

2388 }

2389

2390 SmallVector<IdentifierLoc, 2> Path;

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

2392 return nullptr;

2393

2394

2395 SmallVector<IdentifierLoc, 2> Partition;

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

2399 Diag(ColonLoc, diag::err_unsupported_module_partition)

2400 << SourceRange(ColonLoc, Partition.back().getLoc());

2401

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

2403 return nullptr;

2404 }

2405

2406

2407 ParsedAttributes Attrs(AttrFactory);

2408 MaybeParseCXX11Attributes(Attrs);

2409 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr,

2410 diag::err_keyword_not_module_attr,

2411 false,

2412 true);

2413

2414 ExpectAndConsumeSemi(diag::err_module_expected_semi);

2415

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

2417 ImportState,

2419}

2420

2421Decl *Parser::ParseModuleImport(SourceLocation AtLoc,

2423 SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;

2424

2425 SourceLocation ExportLoc;

2427

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

2429 : Tok.isObjCAtKeyword(tok::objc_import)) &&

2430 "Improper start to module import");

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

2433

2434

2435 SmallVector<IdentifierLoc, 2> Path;

2436 bool IsPartition = false;

2437 Module *HeaderUnit = nullptr;

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

2439

2440

2441

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

2444

2445 HeaderUnit = reinterpret_cast<Module *>(Tok.getAnnotationValue());

2446 ConsumeAnnotationToken();

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

2450 Diag(ColonLoc, diag::err_unsupported_module_partition)

2451 << SourceRange(ColonLoc, Path.back().getLoc());

2452

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

2454 return nullptr;

2455 else

2456 IsPartition = true;

2457 } else {

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

2459 return nullptr;

2460 }

2461

2462 ParsedAttributes Attrs(AttrFactory);

2463 MaybeParseCXX11Attributes(Attrs);

2464

2465 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr,

2466 diag::err_keyword_not_import_attr,

2467 false,

2468 true);

2469

2470 if (PP.hadModuleLoaderFatalFailure()) {

2471

2472 cutOffParsing();

2473 return nullptr;

2474 }

2475

2476

2477 bool SeenError = true;

2478 switch (ImportState) {

2480 SeenError = false;

2481 break;

2483

2484

2486 [[fallthrough]];

2488

2489 if (IsPartition)

2490 Diag(ImportLoc, diag::err_partition_import_outside_module);

2491 else

2492 SeenError = false;

2493 break;

2496

2497

2498

2499

2500

2501

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

2504 Diag(ImportLoc, diag::err_import_in_wrong_fragment)

2505 << IsPartition

2507 else

2508 SeenError = false;

2509 break;

2513 Diag(ImportLoc, diag::err_import_not_allowed_here);

2514 else

2515 SeenError = false;

2516 break;

2517 }

2518 ExpectAndConsumeSemi(diag::err_module_expected_semi);

2520

2521 if (SeenError)

2522 return nullptr;

2523

2525 if (HeaderUnit)

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

2528 else if (!Path.empty())

2529 Import = Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Path,

2530 IsPartition);

2531 if (Import.isInvalid())

2532 return nullptr;

2533

2534

2535

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

2537 auto &SrcMgr = PP.getSourceManager();

2538 auto FE = SrcMgr.getFileEntryRefForID(SrcMgr.getFileID(AtLoc));

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

2540 .ends_with(".framework"))

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

2542 }

2543

2544 return Import.get();

2545}

2546

2547bool Parser::ParseModuleName(SourceLocation UseLoc,

2548 SmallVectorImpl &Path,

2549 bool IsImport) {

2550

2551 while (true) {

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

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

2554 cutOffParsing();

2555 Actions.CodeCompletion().CodeCompleteModuleImport(UseLoc, Path);

2556 return true;

2557 }

2558

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

2561 return true;

2562 }

2563

2564

2565 Path.emplace_back(Tok.getLocation(), Tok.getIdentifierInfo());

2567

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

2569 return false;

2570

2572 }

2573}

2574

2575bool Parser::parseMisplacedModuleImport() {

2576 while (true) {

2577 switch (Tok.getKind()) {

2578 case tok::annot_module_end:

2579

2580

2581

2582 if (MisplacedModuleBeginCount) {

2583 --MisplacedModuleBeginCount;

2584 Actions.ActOnAnnotModuleEnd(

2585 Tok.getLocation(),

2586 reinterpret_cast<Module *>(Tok.getAnnotationValue()));

2587 ConsumeAnnotationToken();

2588 continue;

2589 }

2590

2591

2592

2593 return true;

2594 case tok::annot_module_begin:

2595

2596 Actions.ActOnAnnotModuleBegin(

2597 Tok.getLocation(),

2598 reinterpret_cast<Module *>(Tok.getAnnotationValue()));

2599 ConsumeAnnotationToken();

2600 ++MisplacedModuleBeginCount;

2601 continue;

2602 case tok::annot_module_include:

2603

2604

2605 Actions.ActOnAnnotModuleInclude(

2606 Tok.getLocation(),

2607 reinterpret_cast<Module *>(Tok.getAnnotationValue()));

2608 ConsumeAnnotationToken();

2609

2610 continue;

2611 default:

2612 return false;

2613 }

2614 }

2615 return false;

2616}

2617

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

2619

2620

2621

2623 : diag::ext_c11_feature)

2624 << Tok.getName();

2625}

2626

2627bool BalancedDelimiterTracker::diagnoseOverflow() {

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

2629 << P.getLangOpts().BracketDepth;

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

2631 P.cutOffParsing();

2632 return true;

2633}

2634

2636 const char *Msg,

2638 LOpen = P.Tok.getLocation();

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

2640 if (SkipToTok != tok::unknown)

2642 return true;

2643 }

2644

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

2646 return false;

2647

2648 return diagnoseOverflow();

2649}

2650

2651bool BalancedDelimiterTracker::diagnoseMissingClose() {

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

2653

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

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

2656 else

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

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

2659

2660

2661

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

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

2664 P.SkipUntil(Close, FinalToken,

2666 P.Tok.is(Close))

2667 LClose = P.ConsumeAnyToken();

2668 return true;

2669}

2670

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)

This file defines the classes used to store parsed information about declaration-specifiers and decla...

Defines the C++ template declaration subclasses.

FormatToken * Next

The next token in the unwrapped line.

bool is(tok::TokenKind Kind) const

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

Definition Parser.cpp:118

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

Definition Parser.cpp:283

This file declares facilities that support code completion.

Defines a utilitiy for warning once when close to out of stack space.

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

Definition Parser.cpp:2635

void skipToEnd()

Definition Parser.cpp:2671

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.

virtual void CodeCompletePreprocessorExpression()

Callback invoked when performing code completion in a preprocessor expression, such as the condition ...

virtual void CodeCompleteNaturalLanguage()

Callback invoked when performing code completion in a part of the file where we expect natural langua...

virtual void CodeCompleteInConditionalExclusion()

Callback invoked when performing code completion within a block of code that was excluded due to prep...

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)

void SetRangeStart(SourceLocation Loc)

TSCS getThreadStorageClassSpec() const

ParsedAttributes & getAttributes()

static const TST TST_enum

static bool isDeclRep(TST T)

void takeAttributesAppendingingFrom(ParsedAttributes &attrs)

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

bool isEmpty() const

isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...

SourceLocation getTypeSpecTypeLoc() const

@ PQ_StorageClassSpecifier

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.

void SetRangeBegin(SourceLocation Loc)

SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.

const ParsedAttributes & getAttributes() const

SourceLocation getIdentifierLoc() const

void setFunctionDefinitionKind(FunctionDefinitionKind Val)

DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()

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

A little helper class used to produce diagnostics.

static unsigned getCXXCompatDiagId(const LangOptions &LangOpts, unsigned CompatDiagId)

Get the appropriate diagnostic Id to use for issuing a compatibility diagnostic.

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.

tok::TokenKind getTokenID() const

If this is a source-language token (e.g.

A simple pair of identifier info and location.

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

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.

static OpaquePtr make(TemplateName P)

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

static const ParsedAttributesView & none()

ParsedAttributes - A collection of parsed attributes.

ParseScope - Introduces a new scope for parsing.

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

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Definition Parser.cpp:85

SourceLocation getEndOfPreviousToken() const

Definition Parser.cpp:1871

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

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

Definition Parser.cpp:2013

DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)

Definition Parser.cpp:93

ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)

ParseStringLiteralExpression - This handles the various token types that form string literals,...

SourceLocation ConsumeToken()

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

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

Definition Parser.cpp:56

void EnterScope(unsigned ScopeFlags)

EnterScope - Start a new scope.

Definition Parser.cpp:420

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.

DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)

Parse OpenACC directive on a declaration.

~Parser() override

Definition Parser.cpp:465

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

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

const Token & GetLookAheadToken(unsigned N)

GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.

bool TryConsumeToken(tok::TokenKind Expected)

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

Scope * getCurScope() const

OpaquePtr< TemplateName > TemplateTy

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

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

void SkipMalformedDecl()

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

friend class PoisonSEHIdentifiersRAIIObject

void ExitScope()

ExitScope - Pop a scope off the scope stack.

Definition Parser.cpp:430

const LangOptions & getLangOpts() const

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

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

Definition Parser.cpp:593

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

Definition Parser.cpp:1887

bool MightBeCXXScopeToken()

const Token & NextToken()

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

friend class BalancedDelimiterTracker

SmallVector< TemplateParameterList *, 4 > TemplateParameterLists

void Initialize()

Initialize - Warm up the parser.

Definition Parser.cpp:483

bool TryAnnotateCXXScopeToken(bool EnteringContext=false)

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

Definition Parser.cpp:2130

A class for parsing a DeclSpec.

const ParsingDeclSpec & getDeclSpec() const

ParsingDeclSpec & getMutableDeclSpec() const

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

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.

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.

A (possibly-)qualified type.

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

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.

@ Interface

'export module X;'

@ Implementation

'module X;'

@ Other

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

@ Delete

deleted-function-body

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.

@ ConstantEvaluated

The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...

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.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

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

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

void * getAnnotationValue() const

tok::TokenKind getKind() const

bool hasSeenNoTrivialPPDirective() const

bool isObjCObjectType() const

bool isObjCObjectPointerType() const

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

void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)

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

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

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 '!

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

TypeSpecifierType

Specifies the kind of type.

MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg

@ Unresolved

The identifier can't be resolved.

@ Success

Annotation was successful.

@ Error

Annotation has failed and emitted an error.

@ TentativeDecl

The identifier is a tentatively-declared name.

@ TemplateName

The identifier is a template name. FIXME: Add an annotation for that.

@ Self

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

AccessSpecifier

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

ActionResult< Decl * > DeclResult

nullptr

This class represents a compute construct, representing a 'Kind' of β€˜parallel’, 'serial',...

@ Dependent

Parse the block as a dependent block, which may be used in some template instantiations but not other...

@ Skip

Skip the block entirely; this code is never used.

@ Parse

Parse the block; this code is always used.

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

bool isLambdaCallOperator(const CXXMethodDecl *MD)

@ Result

The result type of a method or function.

ActionResult< ParsedType > TypeResult

const FunctionProtoType * T

@ Template

We are parsing a template declaration.

@ FunctionTemplate

The name was classified as a function template name.

@ Keyword

The name has been typo-corrected to a keyword.

@ DependentNonType

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

@ UndeclaredTemplate

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

@ NonType

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

@ Unknown

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

@ Error

Classification failed; an error has been produced.

@ Type

The name was classified as a type.

@ TypeTemplate

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

@ Concept

The name was classified as a concept name.

@ OverloadSet

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

@ UndeclaredNonType

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

@ VarTemplate

The name was classified as a variable template name.

MutableArrayRef< ParsedTemplateArgument > ASTTemplateArgsPtr

ExtraSemiKind

The kind of extra semi diagnostic to emit.

@ AfterMemberFunctionDefinition

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.

@ Dependent

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

@ Exists

The symbol exists.

@ Error

An error occurred.

@ DoesNotExist

The symbol does not exist.

U cast(CodeGen::Address addr)

SmallVector< Token, 4 > CachedTokens

A set of tokens that has been cached for later parsing.

OpaquePtr< QualType > ParsedType

An opaque type for threading parsed type information through the parser.

ParenParseOption

ParenParseOption - Control what ParseParenExpression will parse.

ActionResult< Expr * > ExprResult

@ Braces

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

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

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.