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