clang: lib/Parse/Parser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
25#include "llvm/Support/Path.h"
26#include "llvm/Support/TimeProfiler.h"
27using namespace clang;
28
29
30namespace {
31
32
35
36public:
37 explicit ActionCommentHandler(Sema &S) : S(S) { }
38
41 return false;
42 }
43};
44}
45
47
50
51 return Ident__except;
52}
53
55 : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
56 Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
57 ColonIsSacred(false), InMessageExpression(false),
58 TemplateParameterDepth(0), ParsingInObjCContainer(false) {
62 Actions.CurScope = nullptr;
63 NumCachedScopes = 0;
64 CurParsedObjCImpl = nullptr;
65
66
67
68 initializePragmaHandlers();
69
70 CommentSemaHandler.reset(new ActionCommentHandler(actions));
72
74
76 [this](StringRef TypeStr, StringRef Context, SourceLocation IncludeLoc) {
77 return this->ParseTypeFromString(TypeStr, Context, IncludeLoc);
78 };
79}
80
83}
84
87}
88
89
90
91
92
93
94
99
100
102 return;
103 }
104
108}
109
111 switch (ExpectedTok) {
112 case tok:🚛
113 return Tok.is(tok::colon) || Tok.is(tok::comma);
114 default: return false;
115 }
116}
117
118bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
119 StringRef Msg) {
120 if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
122 return false;
123 }
124
125
128 {
132 if (DiagID == diag::err_expected)
133 DB << ExpectedTok;
134 else if (DiagID == diag::err_expected_after)
135 DB << Msg << ExpectedTok;
136 else
137 DB << Msg;
138 }
139
140
142 return false;
143 }
144
146 const char *Spelling = nullptr;
149
151 Spelling
153 : Diag(Tok, DiagID);
154 if (DiagID == diag::err_expected)
155 DB << ExpectedTok;
156 else if (DiagID == diag::err_expected_after)
157 DB << Msg << ExpectedTok;
158 else
159 DB << Msg;
160
161 return true;
162}
163
164bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) {
166 return false;
167
168 if (Tok.is(tok::code_completion)) {
169 handleUnexpectedCodeCompletionToken();
170 return false;
171 }
172
173 if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
175 Diag(Tok, diag::err_extraneous_token_before_semi)
180 return false;
181 }
182
183 return ExpectAndConsume(tok::semi, DiagID , TokenUsed);
184}
185
186void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {
187 if (!Tok.is(tok::semi)) return;
188
189 bool HadMultipleSemis = false;
193
195 HadMultipleSemis = true;
198 }
199
200
201
204 Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)
206 else
207 Diag(StartLoc, diag::ext_extra_semi_cxx11)
209 return;
210 }
211
212 if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
213 Diag(StartLoc, diag::ext_extra_semi)
217 else
218
219 Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)
221}
222
223bool Parser::expectIdentifier() {
224 if (Tok.is(tok::identifier))
225 return false;
227 if (II->isCPlusPlusKeyword(getLangOpts())) {
228 Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)
230
231 return false;
232 }
233 }
234 Diag(Tok, diag::err_expected) << tok::identifier;
235 return true;
236}
237
238void Parser::checkCompoundToken(SourceLocation FirstTokLoc,
241 return;
243
244
245
249 Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro)
250 << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
251 << static_cast<int>(Op) << SourceRange(FirstTokLoc);
252 Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here)
255 return;
256 }
257
258
262 SpaceLoc = FirstTokLoc;
263 Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace)
264 << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
265 << static_cast<int>(Op) << SourceRange(FirstTokLoc, SecondTokLoc);
266 return;
267 }
268}
269
270
271
272
273
275 return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
276}
277
278
279
280
281
282
283
284
285
287
288
289 bool isFirstTokenSkipped = true;
290 while (true) {
291
292 for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {
293 if (Tok.is(Toks[i])) {
295
296 } else {
298 }
299 return true;
300 }
301 }
302
303
304
305
306 if (Toks.size() == 1 && Toks[0] == tok::eof &&
309 while (Tok.isNot(tok::eof))
311 return true;
312 }
313
315 case tok::eof:
316
317 return false;
318
319 case tok::annot_pragma_openmp:
320 case tok::annot_attr_openmp:
321 case tok::annot_pragma_openmp_end:
322
323 if (OpenMPDirectiveParsing)
324 return false;
325 ConsumeAnnotationToken();
326 break;
327 case tok::annot_pragma_openacc:
328 case tok::annot_pragma_openacc_end:
329
330 if (OpenACCDirectiveParsing)
331 return false;
332 ConsumeAnnotationToken();
333 break;
334 case tok::annot_module_begin:
335 case tok::annot_module_end:
336 case tok::annot_module_include:
337 case tok::annot_repl_input_end:
338
339
340
341 return false;
342
343 case tok::code_completion:
345 handleUnexpectedCodeCompletionToken();
346 return false;
347
348 case tok::l_paren:
349
350 ConsumeParen();
353 else
355 break;
356 case tok::l_square:
357
358 ConsumeBracket();
361 else
363 break;
364 case tok::l_brace:
365
366 ConsumeBrace();
369 else
371 break;
372 case tok::question:
373
374
379 break;
380
381
382
383
384
385
386 case tok::r_paren:
387 if (ParenCount && !isFirstTokenSkipped)
388 return false;
389 ConsumeParen();
390 break;
391 case tok::r_square:
392 if (BracketCount && !isFirstTokenSkipped)
393 return false;
394 ConsumeBracket();
395 break;
396 case tok::r_brace:
397 if (BraceCount && !isFirstTokenSkipped)
398 return false;
399 ConsumeBrace();
400 break;
401
402 case tok:🚛
404 return false;
405 [[fallthrough]];
406 default:
407
409 break;
410 }
411 isFirstTokenSkipped = false;
412 }
413}
414
415
416
417
418
419
421 if (NumCachedScopes) {
422 Scope *N = ScopeCache[--NumCachedScopes];
424 Actions.CurScope = N;
425 } else {
426 Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags);
427 }
428}
429
430
432 assert(getCurScope() && "Scope imbalance!");
433
434
435
437
439 Actions.CurScope = OldScope->getParent();
440
441 if (NumCachedScopes == ScopeCacheSize)
442 delete OldScope;
443 else
444 ScopeCache[NumCachedScopes++] = OldScope;
445}
446
447
448
449Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
450 bool ManageFlags)
451 : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {
452 if (CurScope) {
453 OldFlags = CurScope->getFlags();
454 CurScope->setFlags(ScopeFlags);
455 }
456}
457
458
459
460Parser::ParseScopeFlags::~ParseScopeFlags() {
461 if (CurScope)
462 CurScope->setFlags(OldFlags);
463}
464
465
466
467
468
469
471
473 Actions.CurScope = nullptr;
474
475
476 for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
477 delete ScopeCache[i];
478
479 resetPragmaHandlers();
480
482
484
485 DestroyTemplateIds();
486}
487
488
489
491
492 assert(getCurScope() == nullptr && "A scope is already active?");
495
496
497
507 ObjCTypeQuals[objc_null_unspecified]
509 }
510
511 Ident_instancetype = nullptr;
512 Ident_final = nullptr;
513 Ident_sealed = nullptr;
514 Ident_abstract = nullptr;
515 Ident_override = nullptr;
516 Ident_GNU_final = nullptr;
517 Ident_import = nullptr;
518 Ident_module = nullptr;
519
521
522 Ident_vector = nullptr;
523 Ident_bool = nullptr;
524 Ident_Bool = nullptr;
525 Ident_pixel = nullptr;
530 }
533
534 Ident_introduced = nullptr;
535 Ident_deprecated = nullptr;
536 Ident_obsoleted = nullptr;
537 Ident_unavailable = nullptr;
538 Ident_strict = nullptr;
539 Ident_replacement = nullptr;
540
541 Ident_language = Ident_defined_in = Ident_generated_declaration = Ident_USR =
542 nullptr;
543
544 Ident__except = nullptr;
545
546 Ident__exception_code = Ident__exception_info = nullptr;
547 Ident__abnormal_termination = Ident___exception_code = nullptr;
548 Ident___exception_info = Ident___abnormal_termination = nullptr;
549 Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;
550 Ident_AbnormalTermination = nullptr;
551
554 Ident___exception_info = PP.getIdentifierInfo("__exception_info");
555 Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation");
557 Ident___exception_code = PP.getIdentifierInfo("__exception_code");
558 Ident_GetExceptionCode = PP.getIdentifierInfo("GetExceptionCode");
559 Ident__abnormal_termination = PP.getIdentifierInfo("_abnormal_termination");
560 Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination");
561 Ident_AbnormalTermination = PP.getIdentifierInfo("AbnormalTermination");
562
563 PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block);
564 PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block);
565 PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block);
566 PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter);
567 PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter);
568 PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter);
569 PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block);
570 PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block);
571 PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);
572 }
573
577 }
578
580
581
583}
584
585void Parser::DestroyTemplateIds() {
587 Id->Destroy();
588 TemplateIds.clear();
589}
590
591
592
593
594
595
596
597
598
599
600
604
605
606
609
610
611
612
613
614
617 Diag(diag::ext_empty_translation_unit);
618
619 return NoTopLevelDecls;
620}
621
622
623
624
625
626
627
630 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
631
634 case tok::annot_pragma_unused:
635 HandlePragmaUnused();
636 return false;
637
638 case tok::kw_export:
640 case tok::kw_module:
641 goto module_decl;
642
643
644
645
646
647
648
649 case tok::identifier: {
651 if ((II == Ident_module || II == Ident_import) &&
652 GetLookAheadToken(2).isNot(tok::coloncolon)) {
653 if (II == Ident_module)
654 goto module_decl;
655 else
656 goto import_decl;
657 }
658 break;
659 }
660
661 default:
662 break;
663 }
664 break;
665
666 case tok::kw_module:
667 module_decl:
668 Result = ParseModuleDecl(ImportState);
669 return false;
670
671 case tok::kw_import:
672 import_decl: {
675 return false;
676 }
677
678 case tok::annot_module_include: {
681
682
685 else {
688 Decl *ImportDecl = Import.isInvalid() ? nullptr : Import.get();
690 }
691 ConsumeAnnotationToken();
692 return false;
693 }
694
695 case tok::annot_module_begin:
699 ConsumeAnnotationToken();
701 return false;
702
703 case tok::annot_module_end:
707 ConsumeAnnotationToken();
709 return false;
710
711 case tok::eof:
712 case tok::annot_repl_input_end:
713
718 if (OverrideLoc.isValid()) {
719 PP.Diag(OverrideLoc, diag::note_max_tokens_total_override);
720 }
721 }
722
723
726
727 return true;
728
729 case tok::identifier:
730
731
732
733
736 NextToken().isNot(tok::coloncolon)) {
738 goto module_decl;
739 else
740 goto import_decl;
741 }
742 break;
743
744 default:
745 break;
746 }
747
750
751
752
753
754 while (MaybeParseCXX11Attributes(DeclAttrs) ||
755 MaybeParseGNUAttributes(DeclSpecAttrs))
756 ;
757
758 Result = ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
759
760
763
766
768 else if (ImportState ==
770
772 }
773 return false;
774}
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
809 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
811
813 cutOffParsing();
814 return nullptr;
815 }
816
817 Decl *SingleDecl = nullptr;
819 case tok::annot_pragma_vis:
820 HandlePragmaVisibility();
821 return nullptr;
822 case tok::annot_pragma_pack:
823 HandlePragmaPack();
824 return nullptr;
825 case tok::annot_pragma_msstruct:
826 HandlePragmaMSStruct();
827 return nullptr;
828 case tok::annot_pragma_align:
829 HandlePragmaAlign();
830 return nullptr;
831 case tok::annot_pragma_weak:
832 HandlePragmaWeak();
833 return nullptr;
834 case tok::annot_pragma_weakalias:
835 HandlePragmaWeakAlias();
836 return nullptr;
837 case tok::annot_pragma_redefine_extname:
838 HandlePragmaRedefineExtname();
839 return nullptr;
840 case tok::annot_pragma_fp_contract:
841 HandlePragmaFPContract();
842 return nullptr;
843 case tok::annot_pragma_fenv_access:
844 case tok::annot_pragma_fenv_access_ms:
845 HandlePragmaFEnvAccess();
846 return nullptr;
847 case tok::annot_pragma_fenv_round:
848 HandlePragmaFEnvRound();
849 return nullptr;
850 case tok::annot_pragma_cx_limited_range:
851 HandlePragmaCXLimitedRange();
852 return nullptr;
853 case tok::annot_pragma_float_control:
854 HandlePragmaFloatControl();
855 return nullptr;
856 case tok::annot_pragma_fp:
857 HandlePragmaFP();
858 break;
859 case tok::annot_pragma_opencl_extension:
860 HandlePragmaOpenCLExtension();
861 return nullptr;
862 case tok::annot_attr_openmp:
863 case tok::annot_pragma_openmp: {
865 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
866 }
867 case tok::annot_pragma_openacc:
869 case tok::annot_pragma_ms_pointers_to_members:
870 HandlePragmaMSPointersToMembers();
871 return nullptr;
872 case tok::annot_pragma_ms_vtordisp:
873 HandlePragmaMSVtorDisp();
874 return nullptr;
875 case tok::annot_pragma_ms_pragma:
876 HandlePragmaMSPragma();
877 return nullptr;
878 case tok::annot_pragma_dump:
879 HandlePragmaDump();
880 return nullptr;
881 case tok::annot_pragma_attribute:
882 HandlePragmaAttribute();
883 return nullptr;
884 case tok:🚛
885
886 SingleDecl =
888 ConsumeExtraSemi(OutsideFunction);
889 break;
890 case tok::r_brace:
891 Diag(Tok, diag::err_extraneous_closing_brace);
892 ConsumeBrace();
893 return nullptr;
894 case tok::eof:
895 Diag(Tok, diag::err_expected_external_declaration);
896 return nullptr;
897 case tok::kw___extension__: {
898
901 return ParseExternalDeclaration(Attrs, DeclSpecAttrs);
902 }
903 case tok::kw_asm: {
904 ProhibitAttributes(Attrs);
905
908
909 ExprResult Result(ParseSimpleAsm( false, &EndLoc));
910
911
912
913
915 const auto *SL = cast(Result.get());
916 if (!SL->getString().trim().empty())
917 Diag(StartLoc, diag::err_gnu_inline_asm_disabled);
918 }
919
920 ExpectAndConsume(tok::semi, diag::err_expected_after,
921 "top-level asm block");
922
923 if (Result.isInvalid())
924 return nullptr;
926 break;
927 }
928 case tok::at:
929 return ParseObjCAtDirectives(Attrs, DeclSpecAttrs);
930 case tok:âž–
931 case tok:âž•
933 Diag(Tok, diag::err_expected_external_declaration);
935 return nullptr;
936 }
937 SingleDecl = ParseObjCMethodDefinition();
938 break;
939 case tok::code_completion:
940 cutOffParsing();
941 if (CurParsedObjCImpl) {
942
945 std::nullopt,
946 nullptr);
947 }
948
950 if (CurParsedObjCImpl) {
954 } else {
956 };
958 return nullptr;
959 case tok::kw_import: {
962 llvm_unreachable("not expecting a c++20 import here");
963 ProhibitAttributes(Attrs);
964 }
965 SingleDecl = ParseModuleImport(SourceLocation(), IS);
966 } break;
967 case tok::kw_export:
969 ProhibitAttributes(Attrs);
970 SingleDecl = ParseExportDeclaration();
971 break;
972 }
973
974
975 [[fallthrough]];
976 case tok::kw_using:
977 case tok::kw_namespace:
978 case tok::kw_typedef:
979 case tok::kw_template:
980 case tok::kw_static_assert:
981 case tok::kw__Static_assert:
982
983 {
986 DeclSpecAttrs);
987 }
988
989 case tok::kw_cbuffer:
990 case tok::kw_tbuffer:
994 DeclSpecAttrs);
995 }
996 goto dont_know;
997
998 case tok::kw_static:
999
1000
1002 Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
1003 << 0;
1006 DeclSpecAttrs);
1007 }
1008 goto dont_know;
1009
1010 case tok::kw_inline:
1013
1014
1015 if (NextKind == tok::kw_namespace) {
1018 DeclSpecAttrs);
1019 }
1020
1021
1022
1023 if (NextKind == tok::kw_template) {
1024 Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
1025 << 1;
1028 DeclSpecAttrs);
1029 }
1030 }
1031 goto dont_know;
1032
1033 case tok::kw_extern:
1035
1039 diag::warn_cxx98_compat_extern_template :
1040 diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
1043 TemplateLoc, DeclEnd, Attrs);
1044 }
1045 goto dont_know;
1046
1047 case tok::kw___if_exists:
1048 case tok::kw___if_not_exists:
1049 ParseMicrosoftIfExistsExternalDeclaration();
1050 return nullptr;
1051
1052 case tok::kw_module:
1053 Diag(Tok, diag::err_unexpected_module_decl);
1055 return nullptr;
1056
1057 default:
1058 dont_know:
1061 return nullptr;
1062 }
1063 if (getLangOpts().IncrementalExtensions &&
1064 !isDeclarationStatement(true))
1065 return ParseTopLevelStmtDecl();
1066
1067
1068 if (!SingleDecl)
1069 return ParseDeclarationOrFunctionDefinition(Attrs, DeclSpecAttrs, DS);
1070 }
1071
1072
1073
1075}
1076
1077
1078
1079bool Parser::isDeclarationAfterDeclarator() {
1080
1083 if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
1084 return false;
1085 }
1086
1087 return Tok.is(tok::equal) ||
1088 Tok.is(tok::comma) ||
1089 Tok.is(tok::semi) ||
1090 Tok.is(tok::kw_asm) ||
1091 Tok.is(tok::kw___attribute) ||
1093 Tok.is(tok::l_paren));
1094}
1095
1096
1097
1100 if (Tok.is(tok::l_brace))
1101 return true;
1102
1103
1107
1110 return KW.is(tok::kw_default) || KW.is(tok::kw_delete);
1111 }
1112
1113 return Tok.is(tok::colon) ||
1114 Tok.is(tok::kw_try);
1115}
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1136
1137
1138
1140 "expected uninitialised source range");
1144
1145 ParsedTemplateInfo TemplateInfo;
1146 MaybeParseMicrosoftAttributes(DS.getAttributes());
1147
1148 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
1149 DeclSpecContext::DSC_top_level);
1150
1151
1152
1153 if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(
1154 DS, AS, DeclSpecContext::DSC_top_level))
1155 return nullptr;
1156
1157
1158
1159 if (Tok.is(tok::semi)) {
1160 auto LengthOfTSTToken = [](DeclSpec::TST TKind) {
1162 switch(TKind) {
1164 return 5;
1166 return 6;
1168 return 5;
1170 return 4;
1172 return 9;
1173 default:
1174 llvm_unreachable("we only expect to get the length of the class/struct/union/enum");
1175 }
1176
1177 };
1178
1184 ProhibitAttributes(Attrs, CorrectLocationForAttributes);
1191 if (AnonRecord) {
1192 Decl* decls[] = {AnonRecord, TheDecl};
1194 }
1196 }
1197
1200
1201
1202
1203
1209 Diag(Tok, diag::err_objc_unexpected_attr);
1211 return nullptr;
1212 }
1213
1216
1217 const char *PrevSpec = nullptr;
1218 unsigned DiagID;
1221 Diag(AtLoc, DiagID) << PrevSpec;
1222
1224 return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
1225
1227 return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes());
1228
1230 ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()));
1231 }
1232
1233
1234
1235
1239 ProhibitAttributes(Attrs);
1242 }
1243
1245}
1246
1250
1251
1252 llvm::TimeTraceScope TimeScope("ParseDeclarationOrFunctionDefinition", [&]() {
1255 });
1256
1257 if (DS) {
1258 return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS);
1259 } else {
1261
1262
1263
1265
1266 return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, PDS, AS);
1267 }
1268}
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1285 const ParsedTemplateInfo &TemplateInfo,
1286 LateParsedAttrList *LateParsedAttrs) {
1287 llvm::TimeTraceScope TimeScope("ParseFunctionDefinition", [&]() {
1289 });
1290
1291
1294 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1295
1296
1297
1298
1299 if (getLangOpts().isImplicitIntRequired() && D.getDeclSpec().isEmpty()) {
1300 Diag(D.getIdentifierLoc(), diag::warn_missing_type_specifier)
1302 const char *PrevSpec;
1303 unsigned DiagID;
1306 D.getIdentifierLoc(),
1307 PrevSpec, DiagID,
1308 Policy);
1310 }
1311
1312
1313
1314
1316 ParseKNRParamDeclarations(D);
1317
1318
1319
1320 if (Tok.isNot(tok::l_brace) &&
1322 (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&
1323 Tok.isNot(tok::equal)))) {
1324 Diag(Tok, diag::err_expected_fn_body);
1325
1326
1328
1329
1330 if (Tok.isNot(tok::l_brace))
1331 return nullptr;
1332 }
1333
1334
1335
1336 if (Tok.isNot(tok::equal)) {
1337 for (const ParsedAttr &AL : D.getAttributes())
1338 if (AL.isKnownToGCC() && !AL.isStandardAttributeSyntax())
1339 Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) << AL;
1340 }
1341
1342
1343
1344 if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
1345 TemplateInfo.Kind == ParsedTemplateInfo::Template &&
1348
1352
1356 D.complete(DP);
1357 D.getMutableDeclSpec().abort();
1358
1360 trySkippingFunctionBody()) {
1361 BodyScope.Exit();
1363 }
1364
1366 LexTemplateFunctionForLateParsing(Toks);
1367
1368 if (DP) {
1372 }
1373 return DP;
1374 }
1375 else if (CurParsedObjCImpl &&
1376 !TemplateInfo.TemplateParams &&
1377 (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
1378 Tok.is(tok::colon)) &&
1383
1387 D.complete(FuncDecl);
1388 D.getMutableDeclSpec().abort();
1389 if (FuncDecl) {
1390
1391 StashAwayMethodOrFunctionBodyTokens(FuncDecl);
1392 CurParsedObjCImpl->HasCFunction = true;
1393 return FuncDecl;
1394 }
1395
1396 }
1397
1398
1401
1402
1403
1408 assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
1409
1412 ? diag::warn_cxx98_compat_defaulted_deleted_function
1413 : diag::ext_defaulted_deleted_function)
1414 << 1 ;
1416 DeletedMessage = ParseCXXDeletedFunctionMessage();
1419 ? diag::warn_cxx98_compat_defaulted_deleted_function
1420 : diag::ext_defaulted_deleted_function)
1421 << 0 ;
1423 } else {
1424 llvm_unreachable("function definition after = not 'delete' or 'default'");
1425 }
1426
1427 if (Tok.is(tok::comma)) {
1428 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
1431 } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
1433 ? "delete"
1434 : "default")) {
1436 }
1437 }
1438
1440
1441
1442
1445 TemplateInfo.TemplateParams
1446 ? *TemplateInfo.TemplateParams
1448 &SkipBody, BodyKind);
1449
1451
1453 SkipFunctionBody();
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1466 return Res;
1467 }
1468
1469
1470 D.complete(Res);
1471
1472
1473
1474 D.getMutableDeclSpec().abort();
1475
1478 Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;
1480 return Res;
1481 }
1482
1483
1484
1485 if (const auto *Template = dyn_cast_if_present(Res);
1486 Template && Template->isAbbreviated() &&
1487 Template->getTemplateParameters()->getParam(0)->isImplicit())
1488
1489
1490 CurTemplateDepthTracker.addDepth(1);
1491
1493 trySkippingFunctionBody()) {
1494 BodyScope.Exit();
1497 }
1498
1499 if (Tok.is(tok::kw_try))
1500 return ParseFunctionTryBlock(Res, BodyScope);
1501
1502
1503
1504 if (Tok.is(tok::colon)) {
1505 ParseConstructorInitializer(Res);
1506
1507
1508 if (!Tok.is(tok::l_brace)) {
1509 BodyScope.Exit();
1511 return Res;
1512 }
1513 } else
1515
1516
1517 if (LateParsedAttrs)
1518 ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
1519
1520 return ParseFunctionStatementBody(Res, BodyScope);
1521}
1522
1523void Parser::SkipFunctionBody() {
1524 if (Tok.is(tok::equal)) {
1526 return;
1527 }
1528
1529 bool IsFunctionTryBlock = Tok.is(tok::kw_try);
1530 if (IsFunctionTryBlock)
1532
1534 if (ConsumeAndStoreFunctionPrologue(Skipped))
1536 else {
1538 while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {
1541 }
1542 }
1543}
1544
1545
1546
1547void Parser::ParseKNRParamDeclarations(Declarator &D) {
1548
1550
1551
1552
1555
1556
1559
1560
1562 ParsedTemplateInfo TemplateInfo;
1563 ParseDeclarationSpecifiers(DS, TemplateInfo);
1564
1565
1566
1567
1568
1569
1571 Diag(DSStart, diag::err_declaration_does_not_declare_param);
1572 continue;
1573 }
1574
1575
1576
1580 diag::err_invalid_storage_class_in_func_decl);
1582 }
1585 diag::err_invalid_storage_class_in_func_decl);
1587 }
1588
1589
1592 ParseDeclarator(ParmDeclarator);
1593
1594
1595 while (true) {
1596
1597 MaybeParseGNUAttributes(ParmDeclarator);
1598
1599
1600 Decl *Param =
1602
1603 if (Param &&
1604
1605 ParmDeclarator.getIdentifier()) {
1606
1607
1608
1609 for (unsigned i = 0; ; ++i) {
1610
1611
1613 Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
1614 << ParmDeclarator.getIdentifier();
1615 break;
1616 }
1617
1618 if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) {
1619
1621 Diag(ParmDeclarator.getIdentifierLoc(),
1622 diag::err_param_redefinition)
1623 << ParmDeclarator.getIdentifier();
1624 } else {
1626 }
1627 break;
1628 }
1629 }
1630 }
1631
1632
1633
1634 if (Tok.isNot(tok::comma))
1635 break;
1636
1637 ParmDeclarator.clear();
1638
1639
1641
1642
1643 ParseDeclarator(ParmDeclarator);
1644 }
1645
1646
1647 if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration))
1648 continue;
1649
1650
1652 break;
1654 }
1655
1656
1658}
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
1671 if (!isTokenStringLiteral()) {
1672 Diag(Tok, diag::err_expected_string_literal)
1673 << 0 << "'asm'";
1675 }
1676
1678 if (!AsmString.isInvalid()) {
1679 const auto *SL = cast(AsmString.get());
1680 if (!SL->isOrdinary()) {
1681 Diag(Tok, diag::err_asm_operand_wide_string_literal)
1682 << SL->isWide()
1683 << SL->getSourceRange();
1685 }
1686 if (ForAsmLabel && SL->getString().empty()) {
1687 Diag(Tok, diag::err_asm_operand_wide_string_literal)
1688 << 2 << SL->getSourceRange();
1690 }
1691 }
1692 return AsmString;
1693}
1694
1695
1696
1697
1698
1699
1701 assert(Tok.is(tok::kw_asm) && "Not an asm!");
1703
1704 if (isGNUAsmQualifier(Tok)) {
1705
1708 Diag(Tok, diag::err_global_asm_qualifier_ignored)
1709 << GNUAsmQualifiers::getQualifierName(getGNUAsmQualifier(Tok))
1712 }
1713
1715 if (T.consumeOpen()) {
1716 Diag(Tok, diag::err_expected_lparen_after) << "asm";
1718 }
1719
1721
1722 if (.isInvalid()) {
1723
1724 T.consumeClose();
1725 if (EndLoc)
1726 *EndLoc = T.getCloseLocation();
1728 if (EndLoc)
1730 ConsumeParen();
1731 }
1732
1734}
1735
1736
1737
1738
1740 assert(tok.is(tok::annot_template_id) && "Expected template-id token");
1743 return Id;
1744}
1745
1746void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
1747
1748
1751 else
1752 PP.EnterToken(Tok, true);
1753 Tok.setKind(tok::annot_cxxscope);
1756
1757
1758
1759
1760 if (IsNewAnnotation)
1762}
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774Parser::AnnotatedNameKind
1777 assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));
1778
1779 const bool EnteringContext = false;
1780 const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
1781
1784 ParseOptionalCXXScopeSpecifier(SS, nullptr,
1785 false,
1786 EnteringContext))
1787 return ANK_Error;
1788
1791 AllowImplicitTypename))
1792 return ANK_Error;
1793 return ANK_Unresolved;
1794 }
1795
1798
1799
1800
1801 if (isTentativelyDeclared(Name) && SS.isEmpty()) {
1802
1803
1805 AllowImplicitTypename))
1806 return ANK_Error;
1807 return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
1808 }
1809
1811
1812
1813
1814
1815
1817 getCurScope(), SS, Name, NameLoc, Next, SS.isEmpty() ? CCC : nullptr);
1818
1819
1820
1821
1822
1824 isTemplateArgumentList(1) == TPResult::False) {
1825
1826 Token FakeNext = Next;
1827 FakeNext.setKind(tok::unknown);
1828 Classification =
1830 SS.isEmpty() ? CCC : nullptr);
1831 }
1832
1833 switch (Classification.getKind()) {
1835 return ANK_Error;
1836
1838
1840 Tok.setKind(Name->getTokenID());
1843 AnnotateScopeToken(SS, !WasScopeAnnotation);
1844
1845 return ANK_Success;
1846
1848
1849 break;
1850
1852 if (TryAltiVecVectorToken())
1853
1854
1855
1856 break;
1860
1861
1862
1867
1871 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
1872 false,
1873 NewEndLoc);
1875 Ty = NewType.get();
1876 else if (Tok.is(tok::eof))
1877 return ANK_Error;
1878 }
1879
1880 Tok.setKind(tok::annot_typename);
1881 setTypeAnnotation(Tok, Ty);
1885 return ANK_Success;
1886 }
1887
1889 Tok.setKind(tok::annot_overload_set);
1890 setExprAnnotation(Tok, Classification.getExpression());
1895 return ANK_Success;
1896
1898 if (TryAltiVecVectorToken())
1899
1900
1901
1902 break;
1903 Tok.setKind(tok::annot_non_type);
1904 setNonTypeAnnotation(Tok, Classification.getNonTypeDecl());
1909 AnnotateScopeToken(SS, !WasScopeAnnotation);
1910 return ANK_Success;
1911
1915 ? tok::annot_non_type_undeclared
1916 : tok::annot_non_type_dependent);
1917 setIdentifierAnnotation(Tok, Name);
1922 AnnotateScopeToken(SS, !WasScopeAnnotation);
1923 return ANK_Success;
1924
1926 if (Next.isNot(tok::less)) {
1927
1929 AnnotateScopeToken(SS, !WasScopeAnnotation);
1930 return ANK_TemplateName;
1931 }
1932 [[fallthrough]];
1938
1939
1940 if (Next.is(tok::less))
1943 Id.setIdentifier(Name, NameLoc);
1944 if (AnnotateTemplateIdToken(
1947 !IsConceptName,
1948 IsConceptName))
1949 return ANK_Error;
1951 AnnotateScopeToken(SS, !WasScopeAnnotation);
1952 return ANK_Success;
1953 }
1954 }
1955
1956
1958 AnnotateScopeToken(SS, !WasScopeAnnotation);
1959 return ANK_Unresolved;
1960}
1961
1962bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
1963 assert(Tok.isNot(tok::identifier));
1964 Diag(Tok, diag::ext_keyword_as_ident)
1966 << DisableKeyword;
1967 if (DisableKeyword)
1969 Tok.setKind(tok::identifier);
1970 return true;
1971}
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1997 assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
1998 Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
1999 Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
2000 Tok.is(tok::kw___super) || Tok.is(tok::kw_auto) ||
2001 Tok.is(tok::annot_pack_indexing_type)) &&
2002 "Cannot be a type or scope token!");
2003
2004 if (Tok.is(tok::kw_typename)) {
2005
2006
2007
2008
2009
2010
2012 Token TypedefToken;
2013 PP.Lex(TypedefToken);
2015 PP.EnterToken(Tok, true);
2016 Tok = TypedefToken;
2018 Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
2020 }
2021
2022
2023
2024
2025
2026
2027
2030 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
2031 false,
2032 false, nullptr,
2033 true))
2034 return true;
2036 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
2037 Tok.is(tok::annot_decltype)) {
2038
2039 if (Tok.is(tok::annot_decltype) ||
2042 unsigned DiagID = diag::err_expected_qualified_after_typename;
2043
2044
2046 DiagID = diag::warn_expected_qualified_after_typename;
2048 return false;
2049 }
2050 }
2052 return true;
2053
2054 Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
2055 return true;
2056 }
2057
2058 bool TemplateKWPresent = false;
2059 if (Tok.is(tok::kw_template)) {
2061 TemplateKWPresent = true;
2062 }
2063
2065 if (Tok.is(tok::identifier)) {
2066 if (TemplateKWPresent && NextToken().isNot(tok::less)) {
2068 diag::missing_template_arg_list_after_template_kw);
2069 return true;
2070 }
2074 } else if (Tok.is(tok::annot_template_id)) {
2077 Diag(Tok, diag::err_typename_refers_to_non_type_template)
2079 return true;
2080 }
2081
2084
2091 TemplateArgsPtr, TemplateId->RAngleLoc);
2092 } else {
2093 Diag(Tok, diag::err_expected_type_name_after_typename)
2095 return true;
2096 }
2097
2099 Tok.setKind(tok::annot_typename);
2100 setTypeAnnotation(Tok, Ty);
2104 return false;
2105 }
2106
2107
2108 bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
2109
2112 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
2113 false,
2114 false))
2115 return true;
2116
2118 AllowImplicitTypename);
2119}
2120
2121
2122
2123
2127 if (Tok.is(tok::identifier)) {
2128
2131 false, NextToken().is(tok::period), nullptr,
2132 false,
2133 true,
2134 true, AllowImplicitTypename)) {
2136 if (SS.isNotEmpty())
2138
2139
2140
2144
2148 = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
2149 false,
2150 NewEndLoc);
2152 Ty = NewType.get();
2153 else if (Tok.is(tok::eof))
2154 return false;
2155 }
2156
2157
2158
2159 Tok.setKind(tok::annot_typename);
2160 setTypeAnnotation(Tok, Ty);
2163
2164
2165
2167 return false;
2168 }
2169
2171
2172
2173
2174 return false;
2175 }
2176
2177
2178
2179
2180 if (NextToken().is(tok::less)) {
2184 bool MemberOfUnknownSpecialization;
2188 nullptr, false, Template,
2189 MemberOfUnknownSpecialization)) {
2190
2191
2193 isTemplateArgumentList(1) != TPResult::False) {
2194
2196 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
2198
2199
2200
2201 return true;
2202 }
2203 }
2204 }
2205 }
2206
2207
2208
2209
2210
2211 }
2212
2213 if (Tok.is(tok::annot_template_id)) {
2216
2217
2218
2219
2220 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
2221 return false;
2222 }
2223 }
2224
2227 Tok.is(tok::coloncolon)) {
2228
2230 return true;
2231 }
2232 return false;
2233 }
2234
2235
2236 AnnotateScopeToken(SS, IsNewScope);
2237 return false;
2238}
2239
2240
2241
2242
2243
2244
2245
2248 "Call sites of this function should be guarded by checking for C++");
2250
2252 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
2253 false,
2254 EnteringContext))
2255 return true;
2257 return false;
2258
2259 AnnotateScopeToken(SS, true);
2260 return false;
2261}
2262
2263bool Parser::isTokenEqualOrEqualTypo() {
2265 switch (Kind) {
2266 default:
2267 return false;
2268 case tok::ampequal:
2269 case tok::starequal:
2270 case tok::plusequal:
2271 case tok::minusequal:
2272 case tok::exclaimequal:
2273 case tok::slashequal:
2274 case tok::percentequal:
2275 case tok::lessequal:
2276 case tok::lesslessequal:
2277 case tok::greaterequal:
2278 case tok::greatergreaterequal:
2279 case tok::caretequal:
2280 case tok::pipeequal:
2281 case tok::equalequal:
2282 Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
2283 << Kind
2285 [[fallthrough]];
2286 case tok::equal:
2287 return true;
2288 }
2289}
2290
2291SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
2292 assert(Tok.is(tok::code_completion));
2294
2296 if (S->isFunctionScope()) {
2297 cutOffParsing();
2300 return PrevTokLocation;
2301 }
2302
2303 if (S->isClassScope()) {
2304 cutOffParsing();
2307 return PrevTokLocation;
2308 }
2309 }
2310
2311 cutOffParsing();
2314 return PrevTokLocation;
2315}
2316
2317
2318
2319void Parser::CodeCompleteDirective(bool InConditional) {
2321}
2322
2323void Parser::CodeCompleteInConditionalExclusion() {
2326}
2327
2328void Parser::CodeCompleteMacroName(bool IsDefinition) {
2330}
2331
2332void Parser::CodeCompletePreprocessorExpression() {
2334}
2335
2336void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
2338 unsigned ArgumentIndex) {
2341}
2342
2343void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {
2345}
2346
2347void Parser::CodeCompleteNaturalLanguage() {
2349}
2350
2351bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
2352 assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
2353 "Expected '__if_exists' or '__if_not_exists'");
2354 Result.IsIfExists = Tok.is(tok::kw___if_exists);
2356
2358 if (T.consumeOpen()) {
2359 Diag(Tok, diag::err_expected_lparen_after)
2360 << (Result.IsIfExists? "__if_exists" : "__if_not_exists");
2361 return true;
2362 }
2363
2364
2366 ParseOptionalCXXScopeSpecifier(Result.SS, nullptr,
2367 false,
2368 false);
2369
2370
2371 if (Result.SS.isInvalid()) {
2372 T.skipToEnd();
2373 return true;
2374 }
2375
2376
2377 SourceLocation TemplateKWLoc;
2379 false, false,
2380 true,
2381 true,
2382 false, &TemplateKWLoc,
2384 T.skipToEnd();
2385 return true;
2386 }
2387
2388 if (T.consumeClose())
2389 return true;
2390
2391
2396 Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip;
2397 break;
2398
2400 Result.Behavior = .IsIfExists ? IEB_Parse : IEB_Skip;
2401 break;
2402
2404 Result.Behavior = IEB_Dependent;
2405 break;
2406
2408 return true;
2409 }
2410
2411 return false;
2412}
2413
2414void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
2415 IfExistsCondition Result;
2416 if (ParseMicrosoftIfExistsCondition(Result))
2417 return;
2418
2420 if (Braces.consumeOpen()) {
2421 Diag(Tok, diag::err_expected) << tok::l_brace;
2422 return;
2423 }
2424
2425 switch (Result.Behavior) {
2426 case IEB_Parse:
2427
2428 break;
2429
2430 case IEB_Dependent:
2431 llvm_unreachable("Cannot have a dependent external declaration");
2432
2433 case IEB_Skip:
2435 return;
2436 }
2437
2438
2439
2440 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2442 MaybeParseCXX11Attributes(Attrs);
2444 DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs);
2447 }
2448 Braces.consumeClose();
2449}
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2467
2471
2472 assert(
2473 (Tok.is(tok::kw_module) ||
2474 (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) &&
2475 "not a module declaration");
2477
2478
2479
2480 DiagnoseAndSkipCXX11Attributes();
2481
2482
2483 if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {
2486 Diag(StartLoc, diag::err_global_module_introducer_not_at_start)
2488 return nullptr;
2489 }
2491 Diag(StartLoc, diag::err_module_fragment_exported)
2493 }
2496 }
2497
2498
2499 if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) &&
2500 NextToken().is(tok::kw_private)) {
2502 Diag(StartLoc, diag::err_module_fragment_exported)
2504 }
2507 DiagnoseAndSkipCXX11Attributes();
2508 ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
2513 }
2514
2516 if (ParseModuleName(ModuleLoc, Path, false))
2517 return nullptr;
2518
2519
2521 if (Tok.is(tok::colon)) {
2524 Diag(ColonLoc, diag::err_unsupported_module_partition)
2525 << SourceRange(ColonLoc, Partition.back().second);
2526
2527 else if (ParseModuleName(ModuleLoc, Partition, false))
2528 return nullptr;
2529 }
2530
2531
2533 MaybeParseCXX11Attributes(Attrs);
2534 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr,
2535 diag::err_keyword_not_module_attr,
2536 false,
2537 true);
2538
2539 ExpectAndConsumeSemi(diag::err_module_expected_semi);
2540
2541 return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, Partition,
2542 ImportState);
2543}
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2563
2566
2567 assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier)
2569 "Improper start to module import");
2570 bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
2572
2573
2575 bool IsPartition = false;
2576 Module *HeaderUnit = nullptr;
2577 if (Tok.is(tok::header_name)) {
2578
2579
2580
2582 } else if (Tok.is(tok::annot_header_unit)) {
2583
2585 ConsumeAnnotationToken();
2586 } else if (Tok.is(tok::colon)) {
2589 Diag(ColonLoc, diag::err_unsupported_module_partition)
2591
2592 else if (ParseModuleName(ColonLoc, Path, true))
2593 return nullptr;
2594 else
2595 IsPartition = true;
2596 } else {
2597 if (ParseModuleName(ImportLoc, Path, true))
2598 return nullptr;
2599 }
2600
2602 MaybeParseCXX11Attributes(Attrs);
2603
2604 ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr,
2605 diag::err_keyword_not_import_attr,
2606 false,
2607 true);
2608
2610
2611 cutOffParsing();
2612 return nullptr;
2613 }
2614
2615
2616 bool SeenError = true;
2617 switch (ImportState) {
2619 SeenError = false;
2620 break;
2622
2623
2625 [[fallthrough]];
2627
2628 if (IsPartition)
2629 Diag(ImportLoc, diag::err_partition_import_outside_module);
2630 else
2631 SeenError = false;
2632 break;
2635
2636
2637
2638
2639
2640
2641 if (IsPartition || (HeaderUnit && HeaderUnit->Kind !=
2643 Diag(ImportLoc, diag::err_import_in_wrong_fragment)
2644 << IsPartition
2646 else
2647 SeenError = false;
2648 break;
2652 Diag(ImportLoc, diag::err_import_not_allowed_here);
2653 else
2654 SeenError = false;
2655 break;
2656 }
2657 ExpectAndConsumeSemi(diag::err_module_expected_semi);
2658
2659 if (SeenError)
2660 return nullptr;
2661
2663 if (HeaderUnit)
2665 Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit);
2666 else if (.empty())
2668 IsPartition);
2669 if (Import.isInvalid())
2670 return nullptr;
2671
2672
2673
2674 if (IsObjCAtImport && AtLoc.isValid()) {
2677 if (FE && llvm::sys::path::parent_path(FE->getDir().getName())
2678 .ends_with(".framework"))
2679 Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);
2680 }
2681
2682 return Import.get();
2683}
2684
2685
2686
2687
2688
2689
2690
2691
2692bool Parser::ParseModuleName(
2695 bool IsImport) {
2696
2697 while (true) {
2698 if (!Tok.is(tok::identifier)) {
2699 if (Tok.is(tok::code_completion)) {
2700 cutOffParsing();
2702 return true;
2703 }
2704
2705 Diag(Tok, diag::err_module_expected_ident) << IsImport;
2707 return true;
2708 }
2709
2710
2713
2714 if (Tok.isNot(tok::period))
2715 return false;
2716
2718 }
2719}
2720
2721
2722
2723
2724
2725bool Parser::parseMisplacedModuleImport() {
2726 while (true) {
2727 switch (Tok.getKind()) {
2728 case tok::annot_module_end:
2729
2730
2731
2732 if (MisplacedModuleBeginCount) {
2733 --MisplacedModuleBeginCount;
2737 ConsumeAnnotationToken();
2738 continue;
2739 }
2740
2741
2742
2743 return true;
2744 case tok::annot_module_begin:
2745
2749 ConsumeAnnotationToken();
2750 ++MisplacedModuleBeginCount;
2751 continue;
2752 case tok::annot_module_include:
2753
2754
2758 ConsumeAnnotationToken();
2759
2760 continue;
2761 default:
2762 return false;
2763 }
2764 }
2765 return false;
2766}
2767
2768void Parser::diagnoseUseOfC11Keyword(const Token &Tok) {
2769
2770
2771
2773 : diag::ext_c11_feature)
2775}
2776
2777bool BalancedDelimiterTracker::diagnoseOverflow() {
2778 P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
2780 P.Diag(P.Tok, diag::note_bracket_depth);
2781 P.cutOffParsing();
2782 return true;
2783}
2784
2786 const char *Msg,
2789 if (P.ExpectAndConsume(Kind, DiagID, Msg)) {
2790 if (SkipToTok != tok::unknown)
2792 return true;
2793 }
2794
2795 if (getDepth() < P.getLangOpts().BracketDepth)
2796 return false;
2797
2798 return diagnoseOverflow();
2799}
2800
2801bool BalancedDelimiterTracker::diagnoseMissingClose() {
2802 assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
2803
2804 if (P.Tok.is(tok::annot_module_end))
2805 P.Diag(P.Tok, diag::err_missing_before_module_end) << Close;
2806 else
2807 P.Diag(P.Tok, diag::err_expected) << Close;
2808 P.Diag(LOpen, diag::note_matching) << Kind;
2809
2810
2811
2812 if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
2813 P.Tok.isNot(tok::r_square) &&
2816 P.Tok.is(Close))
2818 return true;
2819}
2820
2824}
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
Defines the clang::FileManager interface and associated types.
static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok)
static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R)
static std::string getName(const CallEvent &Call)
This file declares facilities that support code completion.
virtual bool HandleTopLevelDecl(DeclGroupRef D)
HandleTopLevelDecl - Handle the specified top-level declaration.
SourceManager & getSourceManager()
const clang::PrintingPolicy & getPrintingPolicy() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
The result of parsing/analyzing an expression, statement etc.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
SourceRange getRange() const
SourceLocation getBeginLoc() const
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool isTranslationUnit() const
Captures information about "declaration specifiers".
void ClearStorageClassSpecs()
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceRange getSourceRange() const LLVM_READONLY
void SetRangeEnd(SourceLocation Loc)
static const TST TST_interface
void SetRangeStart(SourceLocation Loc)
static const TST TST_union
TSCS getThreadStorageClassSpec() const
ParsedAttributes & getAttributes()
static const TST TST_enum
static bool isDeclRep(TST T)
static const TST TST_class
bool hasTagDefinition() const
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
static const TSCS TSCS_unspecified
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_unspecified
SourceLocation getTypeSpecTypeLoc() const
void takeAttributesFrom(ParsedAttributes &attrs)
@ PQ_StorageClassSpecifier
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
A little helper class used to produce diagnostics.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Encapsulates the data about a macro definition (e.g.
Describes a module or submodule.
ModuleKind Kind
The kind of this module.
bool isHeaderUnit() const
Is this module a header unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
Wrapper for void* pointer.
static OpaquePtr make(TemplateName P)
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, bool IsNewScope, ImplicitTypenameContext AllowImplicitTypename)
Try to annotate a type or scope token, having already parsed an optional scope specifier.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
friend class ObjCDeclContextSwitch
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result, Sema::ModuleImportState &ImportState)
Parse the first top-level declaration in a translation unit.
SkipUntilFlags
Control flags for SkipUntil functions.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
bool MightBeCXXScopeToken()
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
void Initialize()
Initialize - Warm up the parser.
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void setCodeCompletionHandler(CodeCompletionHandler &Handler)
Set the code completion handler to the given object.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
void TypoCorrectToken(const Token &Tok)
Update the current token to represent the provided identifier, in order to cache an action performed ...
void AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
void Lex(Token &Result)
Lex the next token for this preprocessor.
void addCommentHandler(CommentHandler *Handler)
Add the specified comment handler to the preprocessor.
void removeCommentHandler(CommentHandler *Handler)
Remove the specified comment handler.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
bool isBacktrackEnabled() const
True if EnableBacktrackAtThisPos() was called and caching of tokens is on.
void SetPoisonReason(IdentifierInfo *II, unsigned DiagID)
Specifies the reason for poisoning an identifier.
void RevertCachedTokens(unsigned N)
When backtracking is enabled and tokens are cached, this allows to revert a specific number of tokens...
unsigned getTokenCount() const
Get the number of tokens processed so far.
unsigned getMaxTokens() const
Get the max number of tokens before issuing a -Wmax-tokens warning.
SourceLocation getMaxTokensOverrideLoc() const
bool hadModuleLoaderFatalFailure() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
IdentifierTable & getIdentifierTable()
void clearCodeCompletionHandler()
Clear out the code completion handler.
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
void Init(Scope *parent, unsigned flags)
Init - This is used by the parser to implement scope caching.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ CompoundStmtScope
This is a compound statement scope.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ DeclScope
This is a scope that can contain a declaration.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_TopLevelOrExpression
Code completion occurs at top-level in a REPL session.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_RecoveryInFunction
Code completion occurs within the body of a function on a recovery path, where we do not have a speci...
void CodeCompletePreprocessorMacroName(bool IsDefinition)
void CodeCompleteInPreprocessorConditionalExclusion(Scope *S)
void CodeCompletePreprocessorExpression()
void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)
void CodeCompletePreprocessorMacroArgument(Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument)
void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path)
void CodeCompleteObjCMethodDecl(Scope *S, std::optional< bool > IsInstanceMethod, ParsedType ReturnType)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteNaturalLanguage()
void CodeCompletePreprocessorDirective(bool InConditional)
Records and restores the CurFPFeatures state on entry/exit of compound statements.
ExprResult getExpression() const
NameClassificationKind getKind() const
NamedDecl * getNonTypeDecl() const
TemplateName getTemplateName() const
ParsedType getType() const
TemplateNameKind getTemplateNameKind() const
Sema - This implements semantic analysis and AST building for C.
void ActOnPopScope(SourceLocation Loc, Scope *S)
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
Decl * ActOnSkippedFunctionBody(Decl *Decl)
void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod)
The parsed has entered a submodule.
void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
The parser has processed a module import translated from a #include or similar preprocessing directiv...
@ IER_DoesNotExist
The symbol does not exist.
@ IER_Dependent
The name is a dependent name, so the results will differ from one instantiation to the next.
@ IER_Error
An error occurred.
@ IER_Exists
The symbol exists.
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
void Initialize()
Perform initialization that occurs after the parser has been initialized but before it parses anythin...
@ Interface
'export module X;'
@ Implementation
'module X;'
void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind, StringLiteral *DeletedMessage=nullptr)
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
void ActOnComment(SourceRange Comment)
@ Other
C++26 [dcl.fct.def.general]p1 function-body: ctor-initializer[opt] compound-statement function-try-bl...
@ Delete
deleted-function-body
void ActOnEndOfTranslationUnit()
ActOnEndOfTranslationUnit - This is called at the very end of the translation unit when EOF is reache...
void ActOnTranslationUnitScope(Scope *S)
Scope actions.
DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, ModuleImportState &ImportState)
The parser has processed a module-declaration that begins the definition of a module interface or imp...
TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool &MemberOfUnknownSpecialization, bool Disambiguation=false)
Decl * ActOnFileScopeAsmDecl(Expr *expr, SourceLocation AsmLoc, SourceLocation RParenLoc)
DeclarationNameInfo GetNameForDeclarator(Declarator &D)
GetNameForDeclarator - Determine the full declaration name for the given Declarator.
void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod)
The parser has left a submodule.
DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path, bool IsPartition=false)
The parser has processed a module import declaration.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ASTContext & getASTContext() const
@ NC_Unknown
This name is not a type or template in this context, but might be something else.
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_TypeTemplate
The name was classified as a template whose specializations are types.
@ NC_Error
Classification failed; an error has been produced.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ NC_UndeclaredNonType
The name was classified as an ADL-only function name.
@ NC_UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NC_Keyword
The name has been typo-corrected to a keyword.
@ NC_Type
The name was classified as a type.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ NC_Concept
The name was classified as a concept name.
void PopExpressionEvaluationContext()
void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, CachedTokens &Toks)
void * SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS)
Given a C++ nested-name-specifier, produce an annotation value that the parser can use later to recon...
void SetLateTemplateParser(LateTemplateParserCB *LTP, LateTemplateParserCleanupCB *LTPCleanup, void *P)
SemaCodeCompletion & CodeCompletion()
ASTConsumer & getASTConsumer() const
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)
bool canDelayFunctionBody(const Declarator &D)
Determine whether we can delay parsing the body of a function or function template until it is used,...
std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback
Callback to the parser to parse a type expressed as a string.
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)
The parser has processed a global-module-fragment declaration that begins the definition of the globa...
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
void CheckForFunctionRedefinition(FunctionDecl *FD, const FunctionDecl *EffectiveDefinition=nullptr, SkipBodyInfo *SkipBody=nullptr)
IfExistsResult CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)
The parser has processed a private-module-fragment declaration that begins the definition of the priv...
bool canSkipFunctionBody(Decl *D)
Determine whether we can skip parsing the body of a function definition, assuming we don't care about...
Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
TypeResult ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS, const IdentifierInfo &II, SourceLocation IdLoc, ImplicitTypenameContext IsImplicitTypename=ImplicitTypenameContext::No)
Called when the parser has parsed a C++ typename specifier, e.g., "typename T::type".
void ActOnStartOfTranslationUnit()
This is called before the very first declaration in the translation unit is parsed.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
@ PrivateFragmentImportFinished
after 'module :private;' but a non-import decl has already been seen.
@ ImportFinished
after any non-import decl.
@ PrivateFragmentImportAllowed
after 'module :private;' but before any non-import decl.
@ FirstDecl
Parsing the first decl in a TU.
@ GlobalFragment
after 'module;' but before 'module X;'
@ NotACXX20Module
Not a C++20 TU, or an invalid state was found.
@ ImportAllowed
after 'module X;' but before any non-import decl.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....
void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls)
Decl * ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList, SourceLocation SemiLoc)
Handle a C++11 empty-declaration and attribute-declaration.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
Represents a C++ template name within the type system.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
const char * getName() const
bool isEditorPlaceholder() const
Returns true if this token is an editor placeholder.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
void setAnnotationValue(void *val)
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void setAnnotationRange(SourceRange R)
void startToken()
Reset all flags to cleared.
void setIdentifierInfo(IdentifierInfo *II)
SourceLocation getLastLoc() const
bool isObjCObjectType() const
bool isObjCObjectPointerType() const
Represents a C++ unqualified-id that has been parsed.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple punctuation tokens like '!' or '', and returns NULL for literal and...
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
@ Braces
New-expression has a C++11 list-initializer.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
bool isKNRPrototype() const
isKNRPrototype - Return true if this is a K&R style identifier list, like "void foo(a,...
const IdentifierInfo * Ident
Wraps an identifier and optional source location for the identifier.
Describes how types, statements, expressions, and declarations should be printed.
Information about a template-id annotation token.
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
bool mightBeType() const
Determine whether this might be a type template.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.