clang: lib/Parse/ParseDeclCXX.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
31#include "llvm/ADT/SmallString.h"
32#include "llvm/Support/TimeProfiler.h"
33#include
34
35using namespace clang;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
67 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
70
71 if (Tok.is(tok::code_completion)) {
72 cutOffParsing();
74 return nullptr;
75 }
76
79 InnerNamespaceInfoList ExtraNSs;
81
83
84 while (MaybeParseGNUAttributes(attrs) || isAllowedCXX11AttributeSpecifier()) {
85 if (isAllowedCXX11AttributeSpecifier()) {
88 ? diag::warn_cxx14_compat_ns_enum_attribute
89 : diag::ext_ns_enum_attribute)
90 << 0 ;
91 ParseCXX11Attributes(attrs);
92 }
93 }
94
95 if (Tok.is(tok::identifier)) {
97 IdentLoc = ConsumeToken();
98 while (Tok.is(tok::coloncolon) &&
99 (NextToken().is(tok::identifier) ||
100 (NextToken().is(tok::kw_inline) &&
101 GetLookAheadToken(2).is(tok::identifier)))) {
102
103 InnerNamespaceInfo Info;
105
106 if (Tok.is(tok::kw_inline)) {
108 if (FirstNestedInlineLoc.isInvalid())
109 FirstNestedInlineLoc = Info.InlineLoc;
110 }
111
114
115 ExtraNSs.push_back(Info);
116 }
117 }
118
119 DiagnoseAndSkipCXX11Attributes();
120 MaybeParseGNUAttributes(attrs);
121 DiagnoseAndSkipCXX11Attributes();
122
124
125
126 if (!ExtraNSs.empty() && attrLoc.isValid())
127 Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
128
129 if (Tok.is(tok::equal)) {
130 if (!Ident) {
131 Diag(Tok, diag::err_expected) << tok::identifier;
132
134 return nullptr;
135 }
136 if (!ExtraNSs.empty()) {
137 Diag(ExtraNSs.front().NamespaceLoc,
138 diag::err_unexpected_qualified_namespace_alias)
139 << SourceRange(ExtraNSs.front().NamespaceLoc,
140 ExtraNSs.back().IdentLoc);
142 return nullptr;
143 }
145 Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
147 Diag(InlineLoc, diag::err_inline_namespace_alias)
149 Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
151 }
152
154 if (T.consumeOpen()) {
155 if (Ident)
156 Diag(Tok, diag::err_expected) << tok::l_brace;
157 else
158 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
159 return nullptr;
160 }
161
165 Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
167 return nullptr;
168 }
169
170 if (ExtraNSs.empty()) {
171
172 } else if (InlineLoc.isValid()) {
173 Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
175 Diag(ExtraNSs[0].NamespaceLoc,
176 diag::warn_cxx14_compat_nested_namespace_definition);
177 if (FirstNestedInlineLoc.isValid())
178 Diag(FirstNestedInlineLoc,
179 diag::warn_cxx17_compat_inline_nested_namespace_definition);
181 Diag(ExtraNSs[0].NamespaceLoc,
182 diag::warn_cxx14_compat_nested_namespace_definition);
183 if (FirstNestedInlineLoc.isValid())
184 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
185 } else {
186 TentativeParsingAction TPA(*this);
188 Token rBraceToken = Tok;
189 TPA.Revert();
190
191 if (!rBraceToken.is(tok::r_brace)) {
192 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
193 << SourceRange(ExtraNSs.front().NamespaceLoc,
194 ExtraNSs.back().IdentLoc);
195 } else {
196 std::string NamespaceFix;
197 for (const auto &ExtraNS : ExtraNSs) {
198 NamespaceFix += " { ";
199 if (ExtraNS.InlineLoc.isValid())
200 NamespaceFix += "inline ";
201 NamespaceFix += "namespace ";
202 NamespaceFix += ExtraNS.Ident->getName();
203 }
204
205 std::string RBraces;
206 for (unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)
207 RBraces += "} ";
208
209 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
211 SourceRange(ExtraNSs.front().NamespaceLoc,
212 ExtraNSs.back().IdentLoc),
213 NamespaceFix)
215 }
216
217
218 if (FirstNestedInlineLoc.isValid())
219 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
220 }
221
222
225 ? diag::warn_cxx98_compat_inline_namespace
226 : diag::ext_inline_namespace);
227
228
230
233 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
234 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false);
235
237 NamespaceLoc, "parsing namespace");
238
239
240
241 ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);
242
243
244 NamespaceScope.Exit();
245
246 DeclEnd = T.getCloseLocation();
248
250 ImplicitUsingDirectiveDecl);
251}
252
253
254void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
258 if (index == InnerNSs.size()) {
259 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
260 Tok.isNot(tok::eof)) {
262 MaybeParseCXX11Attributes(DeclAttrs);
264 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
265 }
266
267
268
270
271 return;
272 }
273
274
275
276
280 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,
281 InnerNSs[index].IdentLoc, InnerNSs[index].Ident,
282 Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true);
283 assert(!ImplicitUsingDirectiveDecl &&
284 "nested namespace definition cannot define anonymous namespace");
285
286 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);
287
288 NamespaceScope.Exit();
290}
291
292
293
294
299 assert(Tok.is(tok::equal) && "Not equal token");
300
302
303 if (Tok.is(tok::code_completion)) {
304 cutOffParsing();
306 return nullptr;
307 }
308
310
311 ParseOptionalCXXScopeSpecifier(SS, nullptr,
312 false,
313 false,
314 nullptr,
315 false,
316 nullptr,
317 true);
318
319 if (Tok.isNot(tok::identifier)) {
320 Diag(Tok, diag::err_expected_namespace_name);
321
323 return nullptr;
324 }
325
327
328
330 return nullptr;
331 }
332
333
336
337
339 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
341
343 Alias, SS, IdentLoc, Ident);
344}
345
346
347
348
349
350
351
352
354 assert(isTokenStringLiteral() && "Not a string literal!");
356
358 Decl *LinkageSpec =
359 Lang.isInvalid()
360 ? nullptr
364
367
368 while (MaybeParseCXX11Attributes(DeclAttrs) ||
369 MaybeParseGNUAttributes(DeclSpecAttrs))
370 ;
371
372 if (Tok.isNot(tok::l_brace)) {
373
374
377
379 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);
382 : nullptr;
383 }
384
386
387 ProhibitAttributes(DeclAttrs);
388
390 T.consumeOpen();
391
392 unsigned NestedModules = 0;
393 while (true) {
395 case tok::annot_module_begin:
396 ++NestedModules;
398 continue;
399
400 case tok::annot_module_end:
401 if (!NestedModules)
402 break;
403 --NestedModules;
405 continue;
406
407 case tok::annot_module_include:
409 continue;
410
411 case tok::eof:
412 break;
413
414 case tok::r_brace:
415 if (!NestedModules)
416 break;
417 [[fallthrough]];
418 default:
421 while (MaybeParseCXX11Attributes(DeclAttrs) ||
422 MaybeParseGNUAttributes(DeclSpecAttrs))
423 ;
424 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
425 continue;
426 }
427
428 break;
429 }
430
431 T.consumeClose();
433 getCurScope(), LinkageSpec, T.getCloseLocation())
434 : nullptr;
435}
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451Decl *Parser::ParseExportDeclaration() {
452 assert(Tok.is(tok::kw_export));
454
455 if (Tok.is(tok::code_completion)) {
456 cutOffParsing();
461 return nullptr;
462 }
463
468
469 if (Tok.isNot(tok::l_brace)) {
470
472 MaybeParseCXX11Attributes(DeclAttrs);
474 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
477 }
478
480 T.consumeOpen();
481
482 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
483 Tok.isNot(tok::eof)) {
485 MaybeParseCXX11Attributes(DeclAttrs);
487 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
488 }
489
490 T.consumeClose();
492 T.getCloseLocation());
493}
494
495
496
498 DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
500 assert(Tok.is(tok::kw_using) && "Not using token");
502
503
505
506 if (Tok.is(tok::code_completion)) {
507 cutOffParsing();
509 return nullptr;
510 }
511
512
513 while (Tok.is(tok::kw_template)) {
515 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
517 }
518
519
520 if (Tok.is(tok::kw_namespace)) {
521
522 if (TemplateInfo.Kind) {
523 SourceRange R = TemplateInfo.getSourceRange();
524 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
526 }
527
528 Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);
530 }
531
532
533 return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,
535}
536
537
538
539
540
541
542
543
544
545
546
551 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
552
553
555
556 if (Tok.is(tok::code_completion)) {
557 cutOffParsing();
559 return nullptr;
560 }
561
563
564 ParseOptionalCXXScopeSpecifier(SS, nullptr,
565 false,
566 false,
567 nullptr,
568 false,
569 nullptr,
570 true);
571
574
575
576 if (Tok.isNot(tok::identifier)) {
577 Diag(Tok, diag::err_expected_namespace_name);
578
580
581 return nullptr;
582 }
583
585
586
588 return nullptr;
589 }
590
591
594
595
596 bool GNUAttr = false;
597 if (Tok.is(tok::kw___attribute)) {
598 GNUAttr = true;
599 ParseGNUAttributes(attrs);
600 }
601
602
604 if (ExpectAndConsume(tok::semi,
605 GNUAttr ? diag::err_expected_semi_after_attribute_list
606 : diag::err_expected_semi_after_namespace_name))
608
610 IdentLoc, NamespcName, attrs);
611}
612
613
614
615
616
617
619 UsingDeclarator &D) {
620 D.clear();
621
622
623
625
626 if (Tok.is(tok::kw___super)) {
627 Diag(Tok.getLocation(), diag::err_super_in_using_declaration);
628 return true;
629 }
630
631
633 if (ParseOptionalCXXScopeSpecifier(D.SS, nullptr,
634 false,
635 false,
636 nullptr,
637 false,
638 &LastII,
639 false,
640 true))
641
642 return true;
643 if (D.SS.isInvalid())
644 return true;
645
646
647
648
649
650
651
652
653
654
655
657 Tok.is(tok::identifier) &&
661 NextToken().is(tok::kw___attribute)) &&
663 .SS.getScopeRep()->getAsNamespace() &&
664 .SS.getScopeRep()->getAsNamespaceAlias()) {
668 D.Name.setConstructorName(Type, IdLoc, IdLoc);
669 } else {
671 D.SS, nullptr,
672 false, false,
673 true,
674
675 !(Tok.is(tok::identifier) && NextToken().is(tok::equal)),
676 false, nullptr, D.Name))
677 return true;
678 }
679
682 ? diag::warn_cxx17_compat_using_declaration_pack
683 : diag::ext_using_declaration_pack);
684
685 return false;
686}
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
712 DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
718
719 if (TryConsumeToken(tok::kw_enum, UELoc) && !InInitStatement) {
720
722 ? diag::warn_cxx17_compat_using_enum_declaration
723 : diag::ext_using_enum_declaration);
724
725 DiagnoseCXX11AttributeExtension(PrefixAttrs);
726
727 if (TemplateInfo.Kind) {
728 SourceRange R = TemplateInfo.getSourceRange();
729 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
732 return nullptr;
733 }
735 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
736 false,
737 false,
738 nullptr,
739 true,
740 nullptr,
741 false,
742 true)) {
744 return nullptr;
745 }
746
747 if (Tok.is(tok::code_completion)) {
748 cutOffParsing();
750 return nullptr;
751 }
752
753 Decl *UED = nullptr;
754
755
756
757 if (Tok.is(tok::identifier)) {
760
762 *IdentInfo, IdentLoc, getCurScope(), &SS, true,
763 false,
764 nullptr, false,
765 true);
766
768 getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, Type, &SS);
769 } else if (Tok.is(tok::annot_template_id)) {
771
774 true);
775
776 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
779 ConsumeAnnotationToken();
780
782 UELoc, Loc, *TemplateId->Name,
783 Type.get(), &SS);
784 } else {
788 }
789 } else {
790 Diag(Tok.getLocation(), diag::err_using_enum_expect_identifier)
791 << Tok.is(tok::kw_enum);
793 return nullptr;
794 }
795
796 if (!UED) {
798 return nullptr;
799 }
800
802 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
803 "using-enum declaration"))
805
807 }
808
809
810
812 MaybeParseCXX11Attributes(MisplacedAttrs);
813
814 if (InInitStatement && Tok.isNot(tok::identifier))
815 return nullptr;
816
817 UsingDeclarator D;
818 bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
819
821 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
822
823
824
825 if (MisplacedAttrs.Range.isValid()) {
826 auto *FirstAttr =
827 MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();
828 auto &Range = MisplacedAttrs.Range;
829 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
830 ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
836 }
837
838
839 if (Tok.is(tok::equal) || InInitStatement) {
840 if (InvalidDeclarator) {
842 return nullptr;
843 }
844
845 ProhibitAttributes(PrefixAttrs);
846
847 Decl *DeclFromDeclSpec = nullptr;
849 if (CurScope)
852
853 Decl *AD = ParseAliasDeclarationAfterDeclarator(
854 TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
856 }
857
858 DiagnoseCXX11AttributeExtension(PrefixAttrs);
859
860
861
862
863 if (TemplateInfo.Kind) {
864 SourceRange R = TemplateInfo.getSourceRange();
865 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
867
868
869
870
871 return nullptr;
872 }
873
875 while (true) {
876
877 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
878 DiagnoseCXX11AttributeExtension(Attrs);
879 Attrs.addAll(PrefixAttrs.begin(), PrefixAttrs.end());
880
881 if (InvalidDeclarator)
883 else {
884
885
886 if (D.TypenameLoc.isValid() &&
889 diag::err_typename_identifiers_only)
891
893 }
894
896 D.TypenameLoc, D.SS, D.Name,
897 D.EllipsisLoc, Attrs);
898 if (UD)
899 DeclsInGroup.push_back(UD);
900 }
901
903 break;
904
905
907 InvalidDeclarator = ParseUsingDeclarator(Context, D);
908 }
909
910 if (DeclsInGroup.size() > 1)
913 ? diag::warn_cxx17_compat_multi_using_declaration
914 : diag::ext_multi_using_declaration);
915
916
918 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
919 !Attrs.empty() ? "attributes list"
920 : UELoc.isValid() ? "using-enum declaration"
921 : "using declaration"))
923
925}
926
927Decl *Parser::ParseAliasDeclarationAfterDeclarator(
928 const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
931 if (ExpectAndConsume(tok::equal)) {
933 return nullptr;
934 }
935
937 ? diag::warn_cxx98_compat_alias_declaration
938 : diag::ext_alias_declaration);
939
940
941 int SpecKind = -1;
942 if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
944 SpecKind = 0;
945 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
946 SpecKind = 1;
947 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
948 SpecKind = 2;
949 if (SpecKind != -1) {
951 if (SpecKind == 0)
953 D.Name.TemplateId->RAngleLoc);
954 else
955 Range = TemplateInfo.getSourceRange();
956 Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
957 << SpecKind << Range;
959 return nullptr;
960 }
961
962
964 Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
965
967 return nullptr;
968 } else if (D.TypenameLoc.isValid())
969 Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)
972 : D.TypenameLoc));
973 else if (D.SS.isNotEmpty())
974 Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
976 if (D.EllipsisLoc.isValid())
977 Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)
979
980 Decl *DeclFromDeclSpec = nullptr;
985 AS, &DeclFromDeclSpec, &Attrs);
986 if (OwnedType)
987 *OwnedType = DeclFromDeclSpec;
988
989
991 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
992 !Attrs.empty() ? "attributes list"
993 : "alias declaration"))
995
998 TemplateParams ? TemplateParams->data() : nullptr,
999 TemplateParams ? TemplateParams->size() : 0);
1001 UsingLoc, D.Name, Attrs, TypeAlias,
1002 DeclFromDeclSpec);
1003}
1004
1007 if (const auto *BO = dyn_cast_or_null(AssertExpr)) {
1008 if (BO->getOpcode() == BO_LAnd &&
1009 isa(BO->getRHS()->IgnoreImpCasts()))
1011 }
1013}
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
1024 assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
1025 "Not a static_assert declaration");
1026
1027
1028 const char *TokName = Tok.getName();
1029
1030 if (Tok.is(tok::kw__Static_assert))
1031 diagnoseUseOfC11Keyword(Tok);
1032 else if (Tok.is(tok::kw_static_assert)) {
1035 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
1036 else
1039 } else
1040 Diag(Tok, diag::warn_cxx98_compat_static_assert);
1041 }
1042
1044
1046 if (T.consumeOpen()) {
1047 Diag(Tok, diag::err_expected) << tok::l_paren;
1049 return nullptr;
1050 }
1051
1055 if (AssertExpr.isInvalid()) {
1057 return nullptr;
1058 }
1059
1061 if (Tok.is(tok::r_paren)) {
1062 unsigned DiagVal;
1064 DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
1066 DiagVal = diag::ext_cxx_static_assert_no_message;
1068 DiagVal = diag::warn_c17_compat_static_assert_no_message;
1069 else
1070 DiagVal = diag::ext_c_static_assert_no_message;
1073 } else {
1074 if (ExpectAndConsume(tok::comma)) {
1076 return nullptr;
1077 }
1078
1079 bool ParseAsExpression = false;
1081 for (unsigned I = 0;; ++I) {
1082 const Token &T = GetLookAheadToken(I);
1083 if (T.is(tok::r_paren))
1084 break;
1086 ParseAsExpression = true;
1087 break;
1088 }
1089 }
1090 }
1091
1092 if (ParseAsExpression) {
1095 ? diag::warn_cxx20_compat_static_assert_user_generated_message
1096 : diag::ext_cxx_static_assert_user_generated_message);
1100 else {
1101 Diag(Tok, diag::err_expected_string_literal)
1102 << 1;
1104 return nullptr;
1105 }
1106
1107 if (AssertMessage.isInvalid()) {
1109 return nullptr;
1110 }
1111 }
1112
1113 if (T.consumeClose())
1114 return nullptr;
1115
1117 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
1118
1120 AssertMessage.get(),
1121 T.getCloseLocation());
1122}
1123
1124
1125
1126
1127
1128
1130 assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype) &&
1131 "Not a decltype specifier");
1132
1136
1137 if (Tok.is(tok::annot_decltype)) {
1138 Result = getExprAnnotation(Tok);
1140
1141
1143 ConsumeAnnotationToken();
1144 if (Result.isInvalid()) {
1146 return EndLoc;
1147 }
1148 } else {
1150 Diag(Tok, diag::warn_cxx98_compat_decltype);
1151
1153
1155 if (T.expectAndConsume(diag::err_expected_lparen_after, "decltype",
1156 tok::r_paren)) {
1158 return T.getOpenLocation() == Tok.getLocation() ? StartLoc
1159 : T.getOpenLocation();
1160 }
1161
1162
1163 if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {
1164
1165
1168 ? diag::warn_cxx11_compat_decltype_auto_type_specifier
1169 : diag::ext_decltype_auto_type_specifier);
1171 } else {
1172
1173
1174
1175
1181 false,
1183 if (Result.isInvalid()) {
1186 EndLoc = ConsumeParen();
1187 } else {
1189
1193 assert(Tok.is(tok::semi));
1194 } else {
1196 }
1197 }
1198 return EndLoc;
1199 }
1200
1202 }
1203
1204
1205 T.consumeClose();
1207 if (T.getCloseLocation().isInvalid()) {
1209
1210
1211 return T.getCloseLocation();
1212 }
1213
1214 if (Result.isInvalid()) {
1216 return T.getCloseLocation();
1217 }
1218
1219 EndLoc = T.getCloseLocation();
1220 }
1221 assert(.isInvalid());
1222
1223 const char *PrevSpec = nullptr;
1224 unsigned DiagID;
1226
1228 PrevSpec, DiagID, Result.get(), Policy)
1230 PrevSpec, DiagID, Policy)) {
1231 Diag(StartLoc, DiagID) << PrevSpec;
1233 }
1234 return EndLoc;
1235}
1236
1237void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
1240
1244
1245
1246
1247
1249 }
1250 } else
1251 PP.EnterToken(Tok, true);
1252
1253 Tok.setKind(tok::annot_decltype);
1254 setExprAnnotation(Tok,
1261}
1262
1264 assert(Tok.isOneOf(tok::annot_pack_indexing_type, tok::identifier) &&
1265 "Expected an identifier");
1266
1270 const char *PrevSpec;
1271 unsigned DiagID;
1273
1274 if (Tok.is(tok::annot_pack_indexing_type)) {
1279
1280
1282 ConsumeAnnotationToken();
1283 if (Type.isInvalid()) {
1285 return EndLoc;
1286 }
1288 DiagID, Type, Policy);
1289 return EndLoc;
1290 }
1291 if (().is(tok::ellipsis) ||
1292 !GetLookAheadToken(2).is(tok::l_square)) {
1295 }
1296
1299 if (!Ty) {
1302 }
1304
1308 T.consumeOpen();
1310 T.consumeClose();
1311
1314
1315 if (!IndexExpr.isUsable()) {
1319 }
1320
1322 Policy);
1324 return T.getCloseLocation();
1325}
1326
1327void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,
1330
1333 if () {
1334
1335
1336
1337
1339 }
1340 } else
1341 PP.EnterToken(Tok, true);
1342
1343 Tok.setKind(tok::annot_pack_indexing_type);
1344 setTypeAnnotation(Tok, T);
1348}
1349
1350DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {
1351 switch (Tok.getKind()) {
1352#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
1353 case tok::kw___##Trait: \
1354 return DeclSpec::TST_##Trait;
1355#include "clang/Basic/TransformTypeTraits.def"
1356 default:
1357 llvm_unreachable("passed in an unhandled type transformation built-in");
1358 }
1359}
1360
1361bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {
1362 if (().is(tok::l_paren)) {
1363 Tok.setKind(tok::identifier);
1364 return false;
1365 }
1366 DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
1368
1370 if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(),
1371 tok::r_paren))
1372 return true;
1373
1375 if (Result.isInvalid()) {
1377 return true;
1378 }
1379
1380 T.consumeClose();
1381 if (T.getCloseLocation().isInvalid())
1382 return true;
1383
1384 const char *PrevSpec = nullptr;
1385 unsigned DiagID;
1386 if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID,
1389 Diag(StartLoc, DiagID) << PrevSpec;
1391 return true;
1392}
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1414
1415 if (Tok.is(tok::kw_typename)) {
1416 Diag(Tok, diag::err_expected_class_name_not_template)
1419 }
1420
1421
1423 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
1424 false,
1425 false))
1426 return true;
1427
1429
1430
1431
1432
1433 if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {
1435 Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
1437
1439
1440 EndLocation = ParseDecltypeSpecifier(DS);
1441
1445 }
1446
1447 if (Tok.is(tok::annot_pack_indexing_type)) {
1449 ParsePackIndexingType(DS);
1453 }
1454
1455
1456
1457
1458 if (Tok.is(tok::annot_template_id)) {
1462 true);
1463
1464 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
1467 ConsumeAnnotationToken();
1468 return Type;
1469 }
1470
1471
1472 }
1473
1474 if (Tok.isNot(tok::identifier)) {
1475 Diag(Tok, diag::err_expected_class_name);
1476 return true;
1477 }
1478
1481
1482 if (Tok.is(tok::less)) {
1483
1484
1485
1486
1490 Template, TNK)) {
1491 Diag(IdLoc, diag::err_unknown_template_name) << Id;
1492 }
1493
1494
1497
1498
1499 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
1501 return true;
1502 if (Tok.is(tok::annot_template_id) &&
1503 takeTemplateIdAnnotation(Tok)->mightBeType())
1505 true);
1506
1507
1508
1509 if (Tok.isNot(tok::annot_typename))
1510 return true;
1511
1512
1513
1516 ConsumeAnnotationToken();
1517 return Type;
1518 }
1519
1520
1523 *Id, IdLoc, getCurScope(), &SS, true, false, nullptr,
1524 false,
1525 true,
1527 &CorrectedII);
1528 if () {
1529 Diag(IdLoc, diag::err_expected_class_name);
1530 return true;
1531 }
1532
1533
1534 EndLocation = IdLoc;
1535
1536
1541
1542 const char *PrevSpec = nullptr;
1543 unsigned DiagID;
1546
1550}
1551
1552void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
1553 while (Tok.isOneOf(tok::kw___single_inheritance,
1554 tok::kw___multiple_inheritance,
1555 tok::kw___virtual_inheritance)) {
1559 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
1560 }
1561}
1562
1563void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {
1564 while (Tok.is(tok::kw__Nullable)) {
1568 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
1569 }
1570}
1571
1572
1573
1574
1575bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
1576
1577 switch (Tok.getKind()) {
1578 default:
1580 return true;
1581 break;
1582 case tok:🚛
1583 case tok:⭐
1584 case tok::amp:
1585 case tok::ampamp:
1586 case tok::identifier:
1587 case tok::r_paren:
1588 case tok::coloncolon:
1589 case tok::annot_cxxscope:
1590 case tok::annot_typename:
1591 case tok::annot_template_id:
1592 case tok::kw_decltype:
1593 case tok::l_paren:
1594 case tok::comma:
1595 case tok::kw_operator:
1596 case tok::kw___declspec:
1597 case tok::l_square:
1598 case tok::ellipsis:
1599
1600
1601 case tok::kw___attribute:
1602 case tok::annot_pragma_pack:
1603
1604 case tok::annot_pragma_ms_pragma:
1605
1606 case tok::annot_pragma_ms_vtordisp:
1607
1608 case tok::annot_pragma_ms_pointers_to_members:
1609 return true;
1610 case tok::colon:
1611 return CouldBeBitfield ||
1612 ColonIsSacred;
1613
1614 case tok::kw___cdecl:
1615 case tok::kw___fastcall:
1616 case tok::kw___stdcall:
1617 case tok::kw___thiscall:
1618 case tok::kw___vectorcall:
1619
1620
1622
1623 case tok::kw_const:
1624 case tok::kw_volatile:
1625 case tok::kw_restrict:
1626 case tok::kw__Atomic:
1627 case tok::kw___unaligned:
1628
1629
1630
1631 case tok::kw_inline:
1632 case tok::kw_virtual:
1633 case tok::kw_friend:
1634
1635 case tok::kw_static:
1636 case tok::kw_extern:
1637 case tok::kw_typedef:
1638 case tok::kw_register:
1639 case tok::kw_auto:
1640 case tok::kw_mutable:
1641 case tok::kw_thread_local:
1642 case tok::kw_constexpr:
1643 case tok::kw_consteval:
1644 case tok::kw_constinit:
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660 if (!isKnownToBeTypeSpecifier(NextToken()))
1661 return true;
1662 break;
1663 case tok::r_brace:
1664
1666 return true;
1667 break;
1668 case tok::greater:
1669
1671 }
1672 return false;
1673}
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
1717 ParsedTemplateInfo &TemplateInfo,
1719 DeclSpecContext DSC,
1722 if (TagTokKind == tok::kw_struct)
1724 else if (TagTokKind == tok::kw___interface)
1726 else if (TagTokKind == tok::kw_class)
1728 else {
1729 assert(TagTokKind == tok::kw_union && "Not a class specifier");
1731 }
1732
1733 if (Tok.is(tok::code_completion)) {
1734
1735 cutOffParsing();
1737 return;
1738 }
1739
1740
1741
1742
1743
1744
1745
1746
1747 const bool shouldDelayDiagsInTag =
1748 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);
1750
1752
1753 for (;;) {
1754 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1755
1756 if (Tok.isOneOf(tok::kw___single_inheritance,
1757 tok::kw___multiple_inheritance,
1758 tok::kw___virtual_inheritance)) {
1759 ParseMicrosoftInheritanceClassAttributes(attrs);
1760 continue;
1761 }
1762 if (Tok.is(tok::kw__Nullable)) {
1763 ParseNullabilityClassAttributes(attrs);
1764 continue;
1765 }
1766 break;
1767 }
1768
1769
1770
1772
1777#include "clang/Basic/TransformTypeTraits.def"
1778 tok::kw___is_abstract,
1779 tok::kw___is_aggregate,
1780 tok::kw___is_arithmetic,
1781 tok::kw___is_array,
1782 tok::kw___is_assignable,
1783 tok::kw___is_base_of,
1784 tok::kw___is_bounded_array,
1785 tok::kw___is_class,
1786 tok::kw___is_complete_type,
1787 tok::kw___is_compound,
1788 tok::kw___is_const,
1789 tok::kw___is_constructible,
1790 tok::kw___is_convertible,
1791 tok::kw___is_convertible_to,
1792 tok::kw___is_destructible,
1793 tok::kw___is_empty,
1794 tok::kw___is_enum,
1795 tok::kw___is_floating_point,
1796 tok::kw___is_final,
1797 tok::kw___is_function,
1798 tok::kw___is_fundamental,
1799 tok::kw___is_integral,
1800 tok::kw___is_interface_class,
1801 tok::kw___is_literal,
1802 tok::kw___is_lvalue_expr,
1803 tok::kw___is_lvalue_reference,
1804 tok::kw___is_member_function_pointer,
1805 tok::kw___is_member_object_pointer,
1806 tok::kw___is_member_pointer,
1807 tok::kw___is_nothrow_assignable,
1808 tok::kw___is_nothrow_constructible,
1809 tok::kw___is_nothrow_convertible,
1810 tok::kw___is_nothrow_destructible,
1811 tok::kw___is_object,
1812 tok::kw___is_pod,
1813 tok::kw___is_pointer,
1814 tok::kw___is_polymorphic,
1815 tok::kw___is_reference,
1816 tok::kw___is_referenceable,
1817 tok::kw___is_rvalue_expr,
1818 tok::kw___is_rvalue_reference,
1819 tok::kw___is_same,
1820 tok::kw___is_scalar,
1821 tok::kw___is_scoped_enum,
1822 tok::kw___is_sealed,
1823 tok::kw___is_signed,
1824 tok::kw___is_standard_layout,
1825 tok::kw___is_trivial,
1826 tok::kw___is_trivially_equality_comparable,
1827 tok::kw___is_trivially_assignable,
1828 tok::kw___is_trivially_constructible,
1829 tok::kw___is_trivially_copyable,
1830 tok::kw___is_unbounded_array,
1831 tok::kw___is_union,
1832 tok::kw___is_unsigned,
1833 tok::kw___is_void,
1834 tok::kw___is_volatile
1835 ))
1836
1837
1838
1839
1840
1841 TryKeywordIdentFallback(true);
1842
1843 struct PreserveAtomicIdentifierInfoRAII {
1844 PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled)
1845 : AtomicII(nullptr) {
1846 if (!Enabled)
1847 return;
1848 assert(Tok.is(tok::kw__Atomic));
1851 Tok.setKind(tok::identifier);
1852 }
1853 ~PreserveAtomicIdentifierInfoRAII() {
1854 if (!AtomicII)
1855 return;
1856 AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
1857 }
1859 };
1860
1861
1862
1863
1864
1865
1866 bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat &&
1867 Tok.is(tok::kw__Atomic) &&
1869 PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
1870 Tok, ShouldChangeAtomicToIdentifier);
1871
1872
1875
1876
1878
1880 if (TemplateInfo.TemplateParams)
1882
1883 bool HasValidSpec = true;
1884 if (ParseOptionalCXXScopeSpecifier(Spec, nullptr,
1885 false,
1886 EnteringContext)) {
1888 HasValidSpec = false;
1889 }
1890 if (Spec.isSet())
1891 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {
1892 Diag(Tok, diag::err_expected) << tok::identifier;
1893 HasValidSpec = false;
1894 }
1895 if (HasValidSpec)
1896 SS = Spec;
1897 }
1898
1900
1901 auto RecoverFromUndeclaredTemplateName = [&](IdentifierInfo *Name,
1904 bool KnownUndeclared) {
1905 Diag(NameLoc, diag::err_explicit_spec_non_template)
1906 << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
1907 << TagTokKind << Name << TemplateArgRange << KnownUndeclared;
1908
1909
1910
1911 if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1912 if (TemplateParams->size() > 1) {
1913 TemplateParams->pop_back();
1914 } else {
1915 TemplateParams = nullptr;
1916 TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;
1917 }
1918 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1919
1920 TemplateParams = nullptr;
1921 TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;
1924 }
1925 };
1926
1927
1931 if (Tok.is(tok::identifier)) {
1935
1937
1938
1939
1940 TemplateArgList TemplateArgs;
1942 if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,
1943 RAngleLoc)) {
1944
1945
1947 }
1948 RecoverFromUndeclaredTemplateName(
1949 Name, NameLoc, SourceRange(LAngleLoc, RAngleLoc), false);
1950 }
1951 } else if (Tok.is(tok::annot_template_id)) {
1952 TemplateId = takeTemplateIdAnnotation(Tok);
1953 NameLoc = ConsumeAnnotationToken();
1954
1956
1960 RecoverFromUndeclaredTemplateName(
1961 Name, NameLoc,
1963 TemplateId = nullptr;
1964 }
1965 }
1966
1967 if (TemplateId && !TemplateId->mightBeType()) {
1968
1969
1970
1974
1975
1976 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
1977 << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
1978
1981 return;
1982 }
1983 }
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012 MaybeParseCXX11Attributes(Attributes);
2013
2016
2017
2018
2019
2021 Tok.isOneOf(tok::comma, tok::ellipsis))
2024 AllowDefiningTypeSpec::No ||
2025 (getLangOpts().OpenMP && OpenMPDirectiveParsing))
2027 else if (Tok.is(tok::l_brace) ||
2028 (DSC != DeclSpecContext::DSC_association &&
2030 (isClassCompatibleKeyword() &&
2033
2034
2035 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
2037
2038
2039
2042 } else {
2043
2045 }
2046 } else if (isClassCompatibleKeyword() &&
2047 (NextToken().is(tok::l_square) ||
2048 NextToken().is(tok::kw_alignas) ||
2051
2052
2053 TentativeParsingAction PA(*this);
2054
2055
2056 while (isClassCompatibleKeyword()) {
2058 }
2059
2060
2061 while (true) {
2062 if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
2063 ConsumeBracket();
2065 break;
2066 } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
2068 ConsumeParen();
2070 break;
2074 if (TakesArgs) {
2076 if (.consumeOpen())
2077 T.skipToEnd();
2078 }
2079 } else {
2080 break;
2081 }
2082 }
2083
2084 if (Tok.isOneOf(tok::l_brace, tok::colon))
2086 else
2088
2089 PA.Revert();
2090 } else if (!isTypeSpecifier(DSC) &&
2091 (Tok.is(tok::semi) ||
2092 (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
2094 if (Tok.isNot(tok::semi)) {
2096
2097 ExpectAndConsume(tok::semi, diag::err_expected_after,
2099 PP.EnterToken(Tok, true);
2101 }
2102 } else
2104
2105
2106
2108
2109
2110
2111
2112
2114 if (AttrRange.isValid()) {
2115 auto *FirstAttr = Attributes.empty() ? nullptr : &Attributes.front();
2117 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
2118 ? Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr
2119 : Diag(Loc, diag::err_attributes_not_allowed))
2120 << AttrRange
2124
2125
2126
2128 }
2129 }
2130
2131 if (!Name && !TemplateId &&
2135
2136 Diag(StartLoc, diag::err_anon_type_definition)
2138 }
2139
2140
2141
2142
2145 else
2147 return;
2148 }
2149
2150
2151 DeclResult TagOrTempResult = true;
2153
2154 bool Owned = false;
2156 if (TemplateId) {
2157
2158
2162
2163 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2165
2166 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2167 diag::err_keyword_not_allowed,
2168 true);
2169
2171 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
2175
2176
2177
2178
2179
2182 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
2183 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2184 diag::err_keyword_not_allowed,
2185 true);
2190 } else {
2191
2192
2194 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2207 "Expected a definition here");
2208
2211 TemplateParams = nullptr;
2212 } else {
2216 diag::err_explicit_instantiation_with_definition)
2217 << SourceRange(TemplateInfo.TemplateLoc)
2219
2220
2221
2222
2224 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2225 LAngleLoc, nullptr));
2226 TemplateParams = &FakedParamLists;
2227 }
2228 }
2229
2230
2233 SS, *TemplateId, attrs,
2235 : nullptr,
2236 TemplateParams ? TemplateParams->size() : 0),
2237 &SkipBody);
2238 }
2239 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2241
2242
2243
2244
2245
2246 ProhibitAttributes(attrs);
2247
2249 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
2250 TagType, StartLoc, SS, Name, NameLoc, attrs);
2252 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
2253 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2254 diag::err_keyword_not_allowed,
2255 true);
2256
2257
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270 if (Tok.is(tok::comma)) {
2272 diag::err_friend_template_decl_multiple_specifiers);
2274 }
2275
2278 NameLoc, EllipsisLoc, attrs,
2280 TemplateParams ? TemplateParams->size() : 0));
2281 } else {
2283 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2284 diag::err_keyword_not_allowed,
2285 true);
2286
2288 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2289
2290
2291 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2293 TemplateParams = nullptr;
2294 }
2295
2296 bool IsDependent = false;
2297
2298
2299
2300
2303 TParams =
2305
2306 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
2307
2308
2309 TagOrTempResult = Actions.ActOnTag(
2310 getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,
2313 DSC == DeclSpecContext::DSC_type_specifier,
2314 DSC == DeclSpecContext::DSC_template_param ||
2315 DSC == DeclSpecContext::DSC_template_type_arg,
2316 OffsetOfState, &SkipBody);
2317
2318
2319
2320 if (IsDependent) {
2323 Name, StartLoc, NameLoc);
2324 }
2325 }
2326
2327
2328
2329
2330 if (shouldDelayDiagsInTag) {
2331 diagsFromTag.done();
2333 TemplateInfo.Kind == ParsedTemplateInfo::Template)
2334 diagsFromTag.redelay();
2335 }
2336
2337
2339 assert(Tok.is(tok::l_brace) ||
2341 isClassCompatibleKeyword());
2343 SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
2344 TagOrTempResult.get());
2346 ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
2347 TagOrTempResult.get());
2348 else {
2351
2352 ParseStructUnionBody(StartLoc, TagType, cast(D));
2356 return;
2357 }
2358 }
2359 }
2360
2361 if (!TagOrTempResult.isInvalid())
2362
2364
2365 const char *PrevSpec = nullptr;
2366 unsigned DiagID;
2370 NameLoc.isValid() ? NameLoc : StartLoc,
2372 } else if (!TagOrTempResult.isInvalid()) {
2374 TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
2375 DiagID, TagOrTempResult.get(), Owned, Policy);
2376 } else {
2378 return;
2379 }
2380
2382 Diag(StartLoc, DiagID) << PrevSpec;
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2398 (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
2399 if (Tok.isNot(tok::semi)) {
2401 ExpectAndConsume(tok::semi, diag::err_expected_after,
2403
2404
2405
2406 PP.EnterToken(Tok, true);
2408 }
2409 }
2410}
2411
2412
2413
2414
2415
2416
2417
2418
2419void Parser::ParseBaseClause(Decl *ClassDecl) {
2420 assert(Tok.is(tok::colon) && "Not a base clause");
2422
2423
2425
2426 while (true) {
2427
2429 if (Result.isInvalid()) {
2430
2431
2433 } else {
2434
2435 BaseInfo.push_back(Result.get());
2436 }
2437
2438
2439
2441 break;
2442 }
2443
2444
2446}
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
2460 bool IsVirtual = false;
2462
2464 MaybeParseCXX11Attributes(Attributes);
2465
2466
2468 IsVirtual = true;
2469
2470 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2471
2472
2474 if (Access != AS_none) {
2477 Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);
2478 }
2479
2480 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2481
2482
2483
2484 if (Tok.is(tok::kw_virtual)) {
2486 if (IsVirtual) {
2487
2488 Diag(VirtualLoc, diag::err_dup_virtual)
2490 }
2491
2492 IsVirtual = true;
2493 }
2494
2495 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2496
2497
2498
2499
2500
2501
2502
2503 if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
2505 Tok.setKind(tok::identifier);
2506
2509 TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
2511 return true;
2512
2513
2514
2515
2518
2519
2521
2522
2523
2525 Access, BaseType.get(), BaseLoc,
2526 EllipsisLoc);
2527}
2528
2529
2530
2531
2532
2533
2534
2535
2536AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
2537 switch (Tok.getKind()) {
2538 default:
2540 case tok::kw_private:
2542 case tok::kw_protected:
2544 case tok::kw_public:
2546 }
2547}
2548
2549
2550
2551
2552
2553void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,
2554 Decl *ThisDecl) {
2556
2557
2559
2560 if (!NeedLateParse) {
2561
2564 if (Param->hasUnparsedDefaultArg()) {
2565 NeedLateParse = true;
2566 break;
2567 }
2568 }
2569 }
2570
2571 if (NeedLateParse) {
2572
2573
2574 auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
2575 getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
2576
2577
2578
2579
2580 LateMethod->DefaultArgs.reserve(FTI.NumParams);
2582 LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
2585
2586
2590 }
2591 }
2592}
2593
2594
2595
2596
2597
2598
2599
2600
2604
2606
2607
2608 if (!Ident_final) {
2615 }
2617 }
2618
2619 if (II == Ident_override)
2621
2622 if (II == Ident_sealed)
2624
2625 if (II == Ident_abstract)
2627
2628 if (II == Ident_final)
2630
2631 if (II == Ident_GNU_final)
2633
2635}
2636
2637
2638
2639
2640
2641
2642void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
2643 bool IsInterface,
2645 while (true) {
2648 return;
2649
2650 if (FriendLoc.isValid()) {
2656 continue;
2657 }
2658
2659
2660
2661 const char *PrevSpec = nullptr;
2663 Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
2665
2668 Diag(Tok.getLocation(), diag::err_override_control_interface)
2676 } else {
2679 ? diag::warn_cxx98_compat_override_control_keyword
2680 : diag::ext_override_control_keyword)
2682 }
2684 }
2685}
2686
2687
2688
2689bool Parser::isCXX11FinalKeyword() const {
2694}
2695
2696
2697
2698bool Parser::isClassCompatibleKeyword() const {
2704}
2705
2706
2707
2708bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
2710 LateParsedAttrList &LateParsedAttrs) {
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721 if (Tok.isNot(tok::colon))
2722 ParseDeclarator(DeclaratorInfo);
2723 else
2725
2727 MaybeParseHLSLAnnotations(DeclaratorInfo, nullptr,
2728 true);
2729
2732 "don't know where identifier would go yet?");
2736 } else if (Tok.is(tok::kw_requires)) {
2737 ParseTrailingRequiresClause(DeclaratorInfo);
2738 } else {
2739 ParseOptionalCXX11VirtSpecifierSeq(
2740 VS, getCurrentClass().IsInterface,
2743 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2744 VS);
2745 }
2746
2747
2748 if (Tok.is(tok::kw_asm)) {
2750 ExprResult AsmLabel(ParseSimpleAsm( true, &Loc));
2751 if (AsmLabel.isInvalid())
2753
2754 DeclaratorInfo.setAsmLabel(AsmLabel.get());
2756 }
2757
2758
2759
2760
2761 DiagnoseAndSkipCXX11Attributes();
2762 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2763 DiagnoseAndSkipCXX11Attributes();
2764
2765
2766
2768 ParseOptionalCXX11VirtSpecifierSeq(
2769 VS, getCurrentClass().IsInterface,
2772
2773
2775 if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
2776 Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
2777
2778 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2779 VS);
2780 }
2781 }
2782
2783
2784
2785 if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
2786
2788 return true;
2789 }
2790 return false;
2791}
2792
2793
2794
2795void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2798
2799
2800
2801 ParseTypeQualifierListOpt(
2802 DS, AR_NoAttributesParsed, false,
2803 false, llvm::function_ref<void()>([&]() {
2804 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D, &VS);
2805 }));
2806 D.ExtendWithDeclSpec(DS);
2807
2808 if (D.isFunctionDeclarator()) {
2809 auto &Function = D.getFunctionTypeInfo();
2811 auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName,
2814 auto &MQ = Function.getOrCreateMethodQualifiers();
2815 if (!(MQ.getTypeQualifiers() & TypeQual)) {
2816 std::string Name(FixItName.data());
2817 Name += " ";
2819 MQ.SetTypeQual(TypeQual, SpecLoc);
2820 }
2821 Diag(SpecLoc, diag::err_declspec_after_virtspec)
2822 << FixItName
2825 };
2827 }
2828
2829
2830 bool RefQualifierIsLValueRef = true;
2832 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
2833 const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");
2836 Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2837 Function.RefQualifierLoc = RefQualifierLoc;
2838
2839 Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
2840 << (RefQualifierIsLValueRef ? "&" : "&&")
2843 D.SetRangeEnd(RefQualifierLoc);
2844 }
2845 }
2846}
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2902 "ParseCXXClassMemberDeclaration should only be called in C++ mode");
2903 if (Tok.is(tok::at)) {
2905 Diag(Tok, diag::err_at_defs_cxx);
2906 else
2907 Diag(Tok, diag::err_at_in_class);
2908
2911 return nullptr;
2912 }
2913
2914
2915
2916
2917
2918
2919
2921
2922
2923 bool MalformedTypeSpec = false;
2924 if (!TemplateInfo.Kind &&
2925 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
2927 MalformedTypeSpec = true;
2928
2929 bool isAccessDecl;
2930 if (Tok.isNot(tok::annot_cxxscope))
2931 isAccessDecl = false;
2932 else if (NextToken().is(tok::identifier))
2933 isAccessDecl = GetLookAheadToken(2).is(tok::semi);
2934 else
2935 isAccessDecl = NextToken().is(tok::kw_operator);
2936
2937 if (isAccessDecl) {
2938
2940 ParseOptionalCXXScopeSpecifier(SS, nullptr,
2941 false,
2942 false);
2943
2946 return nullptr;
2947 }
2948
2949
2953 false, false, true, true,
2954 false, &TemplateKWLoc, Name)) {
2956 return nullptr;
2957 }
2958
2959
2960 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
2961 "access declaration")) {
2963 return nullptr;
2964 }
2965
2966
2972 }
2973 }
2974
2975
2976
2977 if (!TemplateInfo.Kind &&
2978 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2981 DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd)));
2982 }
2983
2984 if (Tok.is(tok::kw_template)) {
2985 assert(!TemplateInfo.TemplateParams &&
2986 "Nested template improperly parsed?");
2990 DeclEnd, AccessAttrs, AS);
2991 }
2992
2993
2994 if (Tok.is(tok::kw___extension__)) {
2995
2998 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
2999 TemplateDiags);
3000 }
3001
3003
3004 MaybeParseCXX11Attributes(DeclAttrs);
3005
3006
3007
3008
3009 if (Tok.is(tok::annot_attr_openmp))
3010 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);
3011
3012 if (Tok.is(tok::kw_using)) {
3013
3015
3016
3017 while (Tok.is(tok::kw_template)) {
3019 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
3021 }
3022
3023 if (Tok.is(tok::kw_namespace)) {
3024 Diag(UsingLoc, diag::err_using_namespace_in_class);
3026 return nullptr;
3027 }
3029
3031 UsingLoc, DeclEnd, DeclAttrs, AS);
3032 }
3033
3035 MaybeParseMicrosoftAttributes(DeclSpecAttrs);
3036
3037
3038 LateParsedAttrList CommonLateParsedAttrs;
3039
3040
3041
3044
3045 if (MalformedTypeSpec)
3047
3048
3049
3050
3051
3052
3053 bool IsTemplateSpecOrInst =
3054 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3055 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3057
3058 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
3059 &CommonLateParsedAttrs);
3060
3061 if (IsTemplateSpecOrInst)
3062 diagsFromTag.done();
3063
3064
3065 X.restore();
3066
3067
3068
3070 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
3071 DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
3072 &CommonLateParsedAttrs))
3073 return nullptr;
3074
3076 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
3077 : nullptr,
3078 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
3079
3082 ProhibitAttributes(DeclAttrs);
3083
3086 getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord);
3088 DS.complete(TheDecl);
3089 if (AnonRecord) {
3090 Decl *decls[] = {AnonRecord, TheDecl};
3092 }
3094 }
3095
3098
3099
3100
3103 ? diag::warn_cxx23_variadic_friends
3104 : diag::ext_variadic_friends);
3105
3108
3109
3113
3117 AnonRecord, VariadicLoc);
3119 if () {
3120 SkipUntil(tok::semi, tok::r_brace);
3121 return true;
3122 }
3123
3124 Decls.push_back(D);
3125 return false;
3126 };
3127
3128 if (ParsedFriendDecl(DS))
3129 return nullptr;
3130
3133 const char *PrevSpec = nullptr;
3134 unsigned DiagId = 0;
3136 ParseDeclarationSpecifiers(DeclSpec, TemplateInfo, AS,
3137 DeclSpecContext::DSC_class, nullptr);
3138 if (ParsedFriendDecl(DeclSpec))
3139 return nullptr;
3140 }
3141
3142 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt,
3143 "friend declaration");
3144
3146 }
3147
3148
3149
3150
3151 if (Tok.is(tok::kw_concept)) {
3155 ? llvm::to_underlying(diag::err_friend_concept)
3156 : llvm::to_underlying(
3157 diag::
3158 err_concept_decls_may_only_appear_in_global_namespace_scope));
3160 return nullptr;
3161 }
3162
3165 if (TemplateInfo.TemplateParams)
3168
3169
3170 LateParsedAttrList LateParsedAttrs;
3171
3174
3175 auto TryConsumePureSpecifier = [&](bool AllowDefinition) {
3176 if (Tok.isNot(tok::equal))
3177 return false;
3178
3181 if (Zero.isNot(tok::numeric_constant) ||
3183 return false;
3184
3185 auto &After = GetLookAheadToken(2);
3186 if (.isOneOf(tok::semi, tok::comma) &&
3187 !(AllowDefinition &&
3188 After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
3189 return false;
3190
3193 return true;
3194 };
3195
3199 bool ExpectSemi = true;
3200
3201
3202
3203
3205
3206
3207 if (ParseCXXMemberDeclaratorBeforeInitializer(
3208 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
3210 return nullptr;
3211 }
3212
3213 if (IsTemplateSpecOrInst)
3214 SAC.done();
3215
3216
3217 if (BitfieldSize.isUnset()) {
3218
3219
3221 TryConsumePureSpecifier( true);
3222
3224
3225
3226
3227
3228
3232 if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
3234 } else if (Tok.is(tok::equal)) {
3236 if (KW.is(tok::kw_default))
3238 else if (KW.is(tok::kw_delete))
3240 else if (KW.is(tok::code_completion)) {
3241 cutOffParsing();
3243 DeclaratorInfo);
3244 return nullptr;
3245 }
3246 }
3247 }
3249
3250
3251
3255
3256
3257 ProhibitAttributes(DeclAttrs);
3258 }
3259
3263 ConsumeBrace();
3265
3266
3268
3269 return nullptr;
3270 }
3271
3274 diag::err_function_declared_typedef);
3275
3276
3278 }
3279
3280 Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,
3281 TemplateInfo, VS, PureSpecLoc);
3282
3283 if (FunDecl) {
3284 for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
3285 CommonLateParsedAttrs[i]->addDecl(FunDecl);
3286 }
3287 for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
3288 LateParsedAttrs[i]->addDecl(FunDecl);
3289 }
3290 }
3291 LateParsedAttrs.clear();
3292
3293
3294 if (Tok.is(tok::semi))
3295 ConsumeExtraSemi(AfterMemberFunctionDefinition);
3296
3298 }
3299 }
3300
3301
3302
3303
3304
3305 while (true) {
3307 bool HasStaticInitializer = false;
3308 if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) {
3309
3310 if (BitfieldSize.isUsable() && !DeclaratorInfo.hasName()) {
3311
3312 Diag(Tok, diag::err_anon_bitfield_member_init);
3315
3316 if (!TryConsumePureSpecifier( false))
3317
3318 HasStaticInitializer = true;
3324 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate) {
3325
3326 if (BitfieldSize.get())
3328 ? diag::warn_cxx17_compat_bitfield_member_init
3329 : diag::ext_bitfield_member_init);
3331 } else {
3332 HasStaticInitializer = true;
3333 }
3334 }
3335
3336
3337
3338
3339
3342
3343
3344
3345
3346
3348 if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {
3349 auto Loc = AL.getRange().getBegin();
3350 (AL.isRegularKeywordAttribute()
3351 ? Diag(Loc, diag::err_keyword_not_allowed) << AL
3352 : Diag(Loc, diag::err_attributes_not_allowed))
3353 << AL.getRange();
3354 }
3355
3357 TemplateParams);
3358 } else {
3360 getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.get(),
3361 VS, HasInClassInit);
3362
3364 ThisDecl ? dyn_cast(ThisDecl) : nullptr)
3365
3366
3367 ThisDecl = VT->getTemplatedDecl();
3368
3369 if (ThisDecl)
3371 }
3372
3373
3374
3376 DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==
3379 HasStaticInitializer = true;
3380 }
3381
3383 Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract";
3384 }
3385 if (ThisDecl && PureSpecLoc.isValid())
3389
3390
3392
3394 ? diag::warn_cxx98_compat_nonstatic_member_init
3395 : diag::ext_nonstatic_member_init);
3396
3397 if (DeclaratorInfo.isArrayOfUnknownBound()) {
3398
3399
3400
3401
3402
3403 Diag(Tok, diag::err_incomplete_array_member_init);
3405
3406
3407 if (ThisDecl)
3409 } else
3410 ParseCXXNonStaticMemberInitializer(ThisDecl);
3411 } else if (HasStaticInitializer) {
3412
3414 ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
3415
3416 if (Init.isInvalid()) {
3417 if (ThisDecl)
3420 } else if (ThisDecl)
3423 } else if (ThisDecl && DeclaratorInfo.isStaticMember())
3424
3426
3427 if (ThisDecl) {
3429
3430 for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
3431 CommonLateParsedAttrs[i]->addDecl(ThisDecl);
3432
3433 for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
3434 LateParsedAttrs[i]->addDecl(ThisDecl);
3435 }
3437 DeclsInGroup.push_back(ThisDecl);
3438
3439 if (DeclaratorInfo.isFunctionDeclarator() &&
3440 DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
3442 HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
3443 }
3444 LateParsedAttrs.clear();
3445
3446 DeclaratorInfo.complete(ThisDecl);
3447
3448
3449
3452 break;
3453
3456
3457
3458
3459 Diag(CommaLoc, diag::err_expected_semi_declaration)
3461 ExpectSemi = false;
3462 break;
3463 }
3464
3465
3466
3467
3468
3469 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3470 DeclaratorInfo.isFirstDeclarator()) {
3471 Diag(CommaLoc, diag::err_multiple_template_declarators)
3472 << TemplateInfo.Kind;
3473 }
3474
3475
3476 DeclaratorInfo.clear();
3478 BitfieldSize = ExprResult(false);
3480 DeclaratorInfo.setCommaLoc(CommaLoc);
3481
3482
3483
3484
3485 DiagnoseAndSkipCXX11Attributes();
3486 MaybeParseGNUAttributes(DeclaratorInfo);
3487 DiagnoseAndSkipCXX11Attributes();
3488
3489 if (ParseCXXMemberDeclaratorBeforeInitializer(
3490 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
3491 break;
3492 }
3493
3494 if (ExpectSemi &&
3495 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
3496
3498
3500 return nullptr;
3501 }
3502
3504}
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
3528 assert(Tok.isOneOf(tok::equal, tok::l_brace) &&
3529 "Data member initializer not starting with '=' or '{'");
3530
3531 bool IsFieldInitialization = isa_and_present(D);
3532
3534 Actions,
3535 IsFieldInitialization
3538 D);
3539
3540
3541
3542
3543 Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
3544 IsFieldInitialization;
3545
3547 if (Tok.is(tok::kw_delete)) {
3548
3549
3550
3551
3552
3554 if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
3555 if (IsFunction)
3556 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
3557 << 1 ;
3558 else
3560 SkipDeletedFunctionBody();
3562 }
3563 } else if (Tok.is(tok::kw_default)) {
3564 if (IsFunction)
3565 Diag(Tok, diag::err_default_delete_in_multiple_declaration)
3566 << 0 ;
3567 else
3571 }
3572 }
3573 if (const auto *PD = dyn_cast_or_null(D)) {
3574 Diag(Tok, diag::err_ms_property_initializer) << PD;
3576 }
3577 return ParseInitializer();
3578}
3579
3583
3585 assert(isCXX11FinalKeyword() && "not a class definition");
3587
3588
3589
3591 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3592
3593
3594
3595
3596 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))
3597 return;
3598 }
3599
3600
3601
3602
3603 if (Tok.is(tok::colon)) {
3604
3606 ParsingClassDefinition ParsingDef(*this, TagDecl, true,
3608 auto OldContext =
3610
3611
3612 ParseBaseClause(nullptr);
3613
3615
3616 if (!Tok.is(tok::l_brace)) {
3618 diag::err_expected_lbrace_after_base_specifiers);
3619 return;
3620 }
3621 }
3622
3623
3624 assert(Tok.is(tok::l_brace));
3626 T.consumeOpen();
3627 T.skipToEnd();
3628
3629
3630 if (Tok.is(tok::kw___attribute)) {
3632 MaybeParseGNUAttributes(Attrs);
3633 }
3634}
3635
3640
3641 switch (Tok.getKind()) {
3642 case tok::kw___if_exists:
3643 case tok::kw___if_not_exists:
3644 ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);
3645 return nullptr;
3646
3647 case tok:🚛
3648
3649 ConsumeExtraSemi(InsideStruct, TagType);
3650 return nullptr;
3651
3652
3653 case tok::annot_pragma_vis:
3654 HandlePragmaVisibility();
3655 return nullptr;
3656 case tok::annot_pragma_pack:
3657 HandlePragmaPack();
3658 return nullptr;
3659 case tok::annot_pragma_align:
3660 HandlePragmaAlign();
3661 return nullptr;
3662 case tok::annot_pragma_ms_pointers_to_members:
3663 HandlePragmaMSPointersToMembers();
3664 return nullptr;
3665 case tok::annot_pragma_ms_pragma:
3666 HandlePragmaMSPragma();
3667 return nullptr;
3668 case tok::annot_pragma_ms_vtordisp:
3669 HandlePragmaMSVtorDisp();
3670 return nullptr;
3671 case tok::annot_pragma_dump:
3672 HandlePragmaDump();
3673 return nullptr;
3674
3675 case tok::kw_namespace:
3676
3677 DiagnoseUnexpectedNamespace(cast(TagDecl));
3678 return nullptr;
3679
3680 case tok::kw_private:
3681
3682
3684 ParsedTemplateInfo TemplateInfo;
3685 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);
3686 }
3687 [[fallthrough]];
3688 case tok::kw_public:
3689 case tok::kw_protected: {
3691 Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);
3693 assert(NewAS != AS_none);
3694
3695 AS = NewAS;
3697 unsigned TokLength = Tok.getLength();
3699 AccessAttrs.clear();
3700 MaybeParseGNUAttributes(AccessAttrs);
3701
3705 Diag(EndLoc, diag::err_expected)
3707 } else {
3709 Diag(EndLoc, diag::err_expected)
3711 }
3712
3713
3714
3716 Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
3717 }
3718
3720
3721 AccessAttrs.clear();
3722 }
3723
3724 return nullptr;
3725 }
3726
3727 case tok::annot_attr_openmp:
3728 case tok::annot_pragma_openmp:
3729 return ParseOpenMPDeclarativeDirectiveWithExtDecl(
3730 AS, AccessAttrs, true, TagType, TagDecl);
3731 case tok::annot_pragma_openacc:
3733
3734 default:
3736 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
3739 ConsumeAnnotationToken();
3740 return nullptr;
3741 }
3742 ParsedTemplateInfo TemplateInfo;
3743 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);
3744 }
3745}
3746
3747
3748
3749
3750
3751
3752
3760 "Invalid TagType!");
3761
3762 llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
3763 if (auto *TD = dyn_cast_or_null(TagDecl))
3764 return TD->getQualifiedNameAsString();
3765 return std::string("");
3766 });
3767
3769 "parsing struct/union/class body");
3770
3771
3772
3773 bool NonNestedClass = true;
3774 if (!ClassStack.empty()) {
3775 for (const Scope *S = getCurScope(); S; S = S->getParent()) {
3776 if (S->isClassScope()) {
3777
3778 NonNestedClass = false;
3779
3780
3781 if (getCurrentClass().IsInterface) {
3782 Diag(RecordLoc, diag::err_invalid_member_in_interface)
3783 << 6
3784 << (isa(TagDecl)
3785 ? cast(TagDecl)->getQualifiedNameAsString()
3786 : "(anonymous)");
3787 }
3788 break;
3789 }
3790
3791 if (S->isFunctionScope())
3792
3793
3794 break;
3795 }
3796 }
3797
3798
3800
3801
3802 ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,
3804
3807
3810 bool IsFinalSpelledSealed = false;
3811 bool IsAbstract = false;
3812
3813
3815 while (true) {
3818 break;
3819 if (isCXX11FinalKeyword()) {
3820 if (FinalLoc.isValid()) {
3822 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3824 } else {
3827 IsFinalSpelledSealed = true;
3828 }
3829 } else {
3830 if (AbstractLoc.isValid()) {
3832 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3834 } else {
3836 IsAbstract = true;
3837 }
3838 }
3840 Diag(FinalLoc, diag::err_override_control_interface)
3844 ? diag::warn_cxx98_compat_override_control_keyword
3845 : diag::ext_override_control_keyword)
3848 Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3850 Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
3852 Diag(FinalLoc, diag::ext_warn_gnu_final);
3853 }
3854 assert((FinalLoc.isValid() || AbstractLoc.isValid()) &&
3855 "not a class definition");
3856
3857
3858
3859
3860
3861 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3862
3863
3864
3865
3866
3867
3868
3869
3870 if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) {
3873 return;
3874 }
3875 }
3876
3877 if (Tok.is(tok::colon)) {
3878 ParseScope InheritanceScope(this, getCurScope()->getFlags() |
3880
3881 ParseBaseClause(TagDecl);
3882 if (!Tok.is(tok::l_brace)) {
3883 bool SuggestFixIt = false;
3886 switch (Tok.getKind()) {
3887 case tok::kw_private:
3888 case tok::kw_protected:
3889 case tok::kw_public:
3891 break;
3892 case tok::kw_static_assert:
3893 case tok::r_brace:
3894 case tok::kw_using:
3895
3896 case tok::kw_template:
3897 SuggestFixIt = true;
3898 break;
3899 case tok::identifier:
3900 SuggestFixIt = isConstructorDeclarator(true);
3901 break;
3902 default:
3903 SuggestFixIt = isCXXSimpleDeclaration(false);
3904 break;
3905 }
3906 }
3908 Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
3909 if (SuggestFixIt) {
3911
3912 PP.EnterToken(Tok, true);
3913 Tok.setKind(tok::l_brace);
3914 } else {
3917 return;
3918 }
3919 }
3920 }
3921
3922 assert(Tok.is(tok::l_brace));
3924 T.consumeOpen();
3925
3928 IsFinalSpelledSealed, IsAbstract,
3929 T.getOpenLocation());
3930
3931
3932
3933
3934
3938 else
3941
3943
3944 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
3945 Tok.isNot(tok::eof)) {
3946
3947 ParseCXXClassMemberDeclarationWithPragmas(
3949 MaybeDestroyTemplateIds();
3950 }
3951 T.consumeClose();
3952 } else {
3954 }
3955
3956
3958 MaybeParseGNUAttributes(attrs);
3959
3962 T.getOpenLocation(),
3963 T.getCloseLocation(), attrs);
3964
3965
3966
3967
3968
3969
3970 if (TagDecl && NonNestedClass) {
3971
3972
3973
3974
3975
3976 SourceLocation SavedPrevTokLocation = PrevTokLocation;
3977 ParseLexedPragmas(getCurrentClass());
3978 ParseLexedAttributes(getCurrentClass());
3979 ParseLexedMethodDeclarations(getCurrentClass());
3980
3981
3983
3984 ParseLexedMemberInitializers(getCurrentClass());
3985 ParseLexedMethodDefs(getCurrentClass());
3986 PrevTokLocation = SavedPrevTokLocation;
3987
3988
3989
3991 }
3992
3995
3996
3997 ParsingDef.Pop();
3998 ClassScope.Exit();
3999}
4000
4001void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {
4002 assert(Tok.is(tok::kw_namespace));
4003
4004
4005
4006 Diag(D->getLocation(), diag::err_missing_end_of_definition) << D;
4007 Diag(Tok.getLocation(), diag::note_missing_end_of_definition_before) << D;
4008
4009
4010 PP.EnterToken(Tok, true);
4011
4015 PP.EnterToken(Tok, true);
4016
4017 Tok.setKind(tok::r_brace);
4018}
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
4042 assert(Tok.is(tok::colon) &&
4043 "Constructor initializer always starts with ':'");
4044
4045
4046
4049
4051 bool AnyErrors = false;
4052
4053 do {
4054 if (Tok.is(tok::code_completion)) {
4055 cutOffParsing();
4057 ConstructorDecl, MemInitializers);
4058 return;
4059 }
4060
4061 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
4063 MemInitializers.push_back(MemInit.get());
4064 else
4065 AnyErrors = true;
4066
4067 if (Tok.is(tok::comma))
4069 else if (Tok.is(tok::l_brace))
4070 break;
4071
4072
4073 else if (!MemInit.isInvalid() &&
4074 Tok.isOneOf(tok::identifier, tok::coloncolon)) {
4076 Diag(Loc, diag::err_ctor_init_missing_comma)
4078 } else {
4079
4082 << tok::l_brace << tok::comma;
4084 break;
4085 }
4086 } while (true);
4087
4089 AnyErrors);
4090}
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
4105
4107 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
4108 false,
4109 false))
4110 return true;
4111
4112
4115
4117
4119
4120 if (Tok.is(tok::identifier)) {
4121
4122
4125 } else if (Tok.is(tok::annot_decltype)) {
4126
4127
4128
4129
4130 ParseDecltypeSpecifier(DS);
4131 } else if (Tok.is(tok::annot_pack_indexing_type)) {
4132
4133
4134 ParsePackIndexingType(DS);
4135 } else {
4137 ? takeTemplateIdAnnotation(Tok)
4138 : nullptr;
4139 if (TemplateId && TemplateId->mightBeType()) {
4141 true);
4142 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
4144 ConsumeAnnotationToken();
4145 } else {
4146 Diag(Tok, diag::err_expected_member_or_base_name);
4147 return true;
4148 }
4149 }
4150
4151
4153 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
4154
4155
4156 ExprResult InitList = ParseBraceInitializer();
4158 return true;
4159
4162
4164 return true;
4166 TemplateTypeTy.get(), DS, IdLoc,
4167 InitList.get(), EllipsisLoc);
4168 } else if (Tok.is(tok::l_paren)) {
4170 T.consumeOpen();
4171
4172
4173 ExprVector ArgExprs;
4174 auto RunSignatureHelp = [&] {
4179 ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,
4180 T.getOpenLocation(), false);
4181 CalledSignatureHelp = true;
4182 return PreferredType;
4183 };
4184 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
4185 PreferredType.enterFunctionArgument(Tok.getLocation(),
4186 RunSignatureHelp);
4187 })) {
4189 RunSignatureHelp();
4191 return true;
4192 }
4193
4194 T.consumeClose();
4195
4198
4200 return true;
4202 ConstructorDecl, getCurScope(), SS, II, TemplateTypeTy.get(), DS, IdLoc,
4203 T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);
4204 }
4205
4207 return true;
4208
4210 return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
4211 else
4212 return Diag(Tok, diag::err_expected) << tok::l_paren;
4213}
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4225 bool Delayed, SourceRange &SpecificationRange,
4230 ExceptionSpecTokens = nullptr;
4231
4232
4233 if (Delayed) {
4234 if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
4236
4237
4238 bool IsNoexcept = Tok.is(tok::kw_noexcept);
4239 Token StartTok = Tok;
4241
4242
4243 if (!Tok.is(tok::l_paren)) {
4244
4245 if (IsNoexcept) {
4246 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
4247 NoexceptExpr = nullptr;
4249 }
4250
4251 Diag(Tok, diag::err_expected_lparen_after) << "throw";
4253 }
4254
4255
4257 ExceptionSpecTokens->push_back(StartTok);
4258 ExceptionSpecTokens->push_back(Tok);
4259 SpecificationRange.setEnd(ConsumeParen());
4260
4261 ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
4262 true,
4263 true);
4264 SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation());
4265
4267 }
4268
4269
4270 if (Tok.is(tok::kw_throw)) {
4271 Result = ParseDynamicExceptionSpecification(
4272 SpecificationRange, DynamicExceptions, DynamicExceptionRanges);
4273 assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
4274 "Produced different number of exception types and ranges.");
4275 }
4276
4277
4278 if (Tok.isNot(tok::kw_noexcept))
4280
4281 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
4282
4283
4284
4287
4289 if (Tok.is(tok::l_paren)) {
4290
4292 T.consumeOpen();
4293
4297
4298 T.consumeClose();
4299 if (!NoexceptExpr.isInvalid()) {
4300 NoexceptExpr =
4302 NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
4303 } else {
4305 }
4306 } else {
4307
4309 NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
4310 }
4311
4313 SpecificationRange = NoexceptRange;
4314 Result = NoexceptType;
4315
4316
4317
4318 if (Tok.is(tok::kw_throw)) {
4319 Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
4320 ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
4321 DynamicExceptionRanges);
4322 }
4323 } else {
4324 Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
4325 }
4326
4328}
4329
4331 bool IsNoexcept) {
4332 if (P.getLangOpts().CPlusPlus11) {
4333 const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
4334 P.Diag(Range.getBegin(), P.getLangOpts().CPlusPlus17 && !IsNoexcept
4335 ? diag::ext_dynamic_exception_spec
4336 : diag::warn_exception_spec_deprecated)
4338 P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
4340 }
4341}
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4357 assert(Tok.is(tok::kw_throw) && "expected throw");
4358
4361 if (T.consumeOpen()) {
4362 Diag(Tok, diag::err_expected_lparen_after) << "throw";
4363 SpecificationRange.setEnd(SpecificationRange.getBegin());
4365 }
4366
4367
4368
4369 if (Tok.is(tok::ellipsis)) {
4372 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
4373 T.consumeClose();
4374 SpecificationRange.setEnd(T.getCloseLocation());
4377 }
4378
4379
4381 while (Tok.isNot(tok::r_paren)) {
4383
4384 if (Tok.is(tok::ellipsis)) {
4385
4386
4387
4390 if (!Res.isInvalid())
4392 }
4393
4394 if (!Res.isInvalid()) {
4395 Exceptions.push_back(Res.get());
4396 Ranges.push_back(Range);
4397 }
4398
4400 break;
4401 }
4402
4403 T.consumeClose();
4404 SpecificationRange.setEnd(T.getCloseLocation());
4406 Exceptions.empty());
4408}
4409
4410
4411
4413 bool MayBeFollowedByDirectInit) {
4414 assert(Tok.is(tok::arrow) && "expected arrow");
4415
4417
4421}
4422
4423
4424void Parser::ParseTrailingRequiresClause(Declarator &D) {
4425 assert(Tok.is(tok::kw_requires) && "expected requires");
4426
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4443 DeclaratorScopeObj DeclScopeObj(*this, SS);
4445 DeclScopeObj.EnterDeclaratorScope();
4446
4451
4453
4454 std::optionalSema::CXXThisScopeRAII ThisScope;
4455 InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope);
4456
4457 TrailingRequiresClause =
4459
4460 TrailingRequiresClause =
4462
4463 if (.isDeclarationOfFunction()) {
4464 Diag(RequiresKWLoc,
4465 diag::err_requires_clause_on_declarator_not_declaring_a_function);
4466 return;
4467 }
4468
4469 if (TrailingRequiresClause.isInvalid())
4470 SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},
4472 else
4473 D.setTrailingRequiresClause(TrailingRequiresClause.get());
4474
4475
4476 if (D.isFunctionDeclarator() && Tok.is(tok::arrow) &&
4477 D.getDeclSpec().getTypeSpecType() == TST_auto) {
4481 ParseTrailingReturnType(Range, false);
4482
4483 if (!TrailingReturnType.isInvalid()) {
4484 Diag(ArrowLoc,
4485 diag::err_requires_clause_must_appear_after_trailing_return)
4487 auto &FunctionChunk = D.getFunctionTypeInfo();
4488 FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable();
4489 FunctionChunk.TrailingReturnType = TrailingReturnType.get();
4490 FunctionChunk.TrailingReturnTypeLoc = Range.getBegin();
4491 } else
4492 SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},
4494 }
4495}
4496
4497
4498
4499
4501 bool NonNestedClass,
4502 bool IsInterface) {
4503 assert((NonNestedClass || !ClassStack.empty()) &&
4504 "Nested class without outer class");
4505 ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
4507}
4508
4509
4510
4511void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
4512 for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
4513 delete Class->LateParsedDeclarations[I];
4515}
4516
4517
4518
4519
4520
4521
4522
4524 assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
4525
4527
4528 ParsingClass *Victim = ClassStack.top();
4529 ClassStack.pop();
4530 if (Victim->TopLevelClass) {
4531
4532
4533 DeallocateParsedClasses(Victim);
4534 return;
4535 }
4536 assert(!ClassStack.empty() && "Missing top-level class?");
4537
4538 if (Victim->LateParsedDeclarations.empty()) {
4539
4540
4541
4542
4543 DeallocateParsedClasses(Victim);
4544 return;
4545 }
4546
4547
4548
4549
4551 "Nested class outside of class scope?");
4552 ClassStack.top()->LateParsedDeclarations.push_back(
4553 new LateParsedClass(this, Victim));
4554}
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(
4568 switch (Tok.getKind()) {
4569 default:
4570
4574 return II;
4575 }
4576 }
4577 return nullptr;
4578
4579 case tok::code_completion:
4580 cutOffParsing();
4583 Completion, Scope);
4584 return nullptr;
4585
4586 case tok::numeric_constant: {
4587
4588
4589
4594 StringRef Spelling = PP.getSpelling(ExpansionLoc, ExpansionBuf);
4595 if (Spelling == "__clang__") {
4597 ExpansionLoc,
4599 Diag(Tok, diag::warn_wrong_clang_attr_namespace)
4603 }
4604 }
4605 return nullptr;
4606 }
4607
4608 case tok::ampamp:
4609 case tok::pipe:
4610 case tok::pipepipe:
4611 case tok::caret:
4612 case tok::tilde:
4613 case tok::amp:
4614 case tok::ampequal:
4615 case tok::pipeequal:
4616 case tok::caretequal:
4617 case tok::exclaim:
4618 case tok::exclaimequal:
4619
4620
4624 StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);
4625 if (isLetter(Spelling[0])) {
4628 }
4629 return nullptr;
4630 }
4631}
4632
4633void Parser::ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
4635
4636
4638 if (T.consumeOpen()) {
4639 Diag(Tok, diag::err_expected) << tok::l_paren;
4640 return;
4641 }
4642
4643 if (AttrName->isStr("directive")) {
4644
4645
4646
4647 Token OMPBeginTok;
4649 OMPBeginTok.setKind(tok::annot_attr_openmp);
4651 OpenMPTokens.push_back(OMPBeginTok);
4652
4653 ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens, false,
4654 false);
4655 Token OMPEndTok;
4657 OMPEndTok.setKind(tok::annot_pragma_openmp_end);
4659 OpenMPTokens.push_back(OMPEndTok);
4660 } else {
4661 assert(AttrName->isStr("sequence") &&
4662 "Expected either 'directive' or 'sequence'");
4663
4664
4665
4666 do {
4667
4668
4669
4671 const IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4672
4673
4674
4675 if (Ident && Ident->isStr("omp") && !ExpectAndConsume(tok::coloncolon))
4676 Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4677
4678
4679
4680 if (!Ident || (!Ident->isStr("directive") && !Ident->isStr("sequence"))) {
4681 Diag(Tok.getLocation(), diag::err_expected_sequence_or_directive);
4683 continue;
4684 }
4685
4686
4687 ParseOpenMPAttributeArgs(Ident, OpenMPTokens);
4688
4689
4690
4692 }
4693
4694 T.consumeClose();
4695}
4696
4699 switch (
4701 case ParsedAttr::AT_CarriesDependency:
4702 case ParsedAttr::AT_Deprecated:
4703 case ParsedAttr::AT_FallThrough:
4704 case ParsedAttr::AT_CXX11NoReturn:
4705 case ParsedAttr::AT_NoUniqueAddress:
4706 case ParsedAttr::AT_Likely:
4707 case ParsedAttr::AT_Unlikely:
4708 return true;
4709 case ParsedAttr::AT_WarnUnusedResult:
4710 return !ScopeName && AttrName->getName() == "nodiscard";
4711 case ParsedAttr::AT_Unused:
4712 return !ScopeName && AttrName->getName() == "maybe_unused";
4713 default:
4714 return false;
4715 }
4716}
4717
4718
4719bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
4724 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
4726 T.consumeOpen();
4727
4728
4731
4732 TentativeParsingAction TPA(*this);
4735 if (Res.isInvalid()) {
4736 TPA.Commit();
4738 if (Tok.is(tok::r_paren))
4739 T.consumeClose();
4740 return true;
4741 }
4742
4743 if (!Tok.isOneOf(tok::r_paren, tok::r_square)) {
4744
4745
4746 TPA.Revert();
4748 if (!Res.isInvalid()) {
4749 auto *E = Res.get();
4750 Diag(E->getExprLoc(), diag::err_assume_attr_expects_cond_expr)
4753 ")")
4755 }
4756
4757 T.consumeClose();
4758 return true;
4759 }
4760
4761 TPA.Commit();
4762 ArgsUnion Assumption = Res.get();
4764 T.consumeClose();
4765 Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), nullptr,
4767
4768 if (EndLoc)
4769 *EndLoc = RParen;
4770
4771 return false;
4772}
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788bool Parser::ParseCXX11AttributeArgs(
4792 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
4796 LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23();
4797
4798
4802 Form = ParsedAttr::Form::Microsoft();
4803 }
4804
4805
4806
4811
4812 ConsumeParen();
4814 return false;
4815 }
4816
4817 if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) {
4818
4819
4820 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
4821 ScopeLoc, Form, nullptr);
4822 return true;
4823 }
4824
4825
4826 if (ScopeName && ScopeName->isStr("omp") &&
4827 (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {
4829 ? diag::warn_omp51_compat_attributes
4830 : diag::ext_omp_attributes);
4831
4832 ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);
4833
4834
4835
4836 return true;
4837 }
4838
4839 unsigned NumArgs;
4840
4841 if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))
4842 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
4843 ScopeName, ScopeLoc, Form);
4844
4845 else if (!ScopeName && AttrName->isStr("assume")) {
4846 if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form))
4847 return true;
4848 NumArgs = 1;
4849 } else
4850 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
4851 ScopeName, ScopeLoc, Form);
4852
4853 if (!Attrs.empty() &&
4856
4857
4859 Diag(LParenLoc, diag::warn_unknown_attribute_ignored) << AttrName;
4860 Attr.setInvalid(true);
4861 return true;
4862 }
4863
4864
4865
4866
4867
4868 if (Attr.getMaxArgs() && !NumArgs) {
4869
4870
4871 Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
4872 Attr.setInvalid(true);
4873 } else if (.getMaxArgs()) {
4874
4875
4876
4877 Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
4878 << AttrName
4880 Attr.setInvalid(true);
4881 }
4882 }
4883 return true;
4884}
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
4913 if (Tok.is(tok::kw_alignas)) {
4914
4915
4916
4917
4919 Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
4920 ParseAlignmentSpecifier(Attrs, EndLoc);
4921 return;
4922 }
4923
4930 if (TakesArgs) {
4931 if (!Tok.is(tok::l_paren))
4932 Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;
4933 else
4934 ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,
4935 nullptr,
4936 Loc, Form);
4937 } else
4938 Attrs.addNew(AttrName, Loc, nullptr, Loc, nullptr, 0, Form);
4939 return;
4940 }
4941
4942 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) &&
4943 "Not a double square bracket attribute list");
4944
4948 : diag::warn_ext_cxx11_attributes);
4949 } else {
4950 Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes
4951 : diag::warn_ext_c23_attributes);
4952 }
4953
4954 ConsumeBracket();
4955 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
4956 ConsumeBracket();
4957
4960 if (Tok.is(tok::kw_using)) {
4962 ? diag::warn_cxx14_compat_using_attribute_ns
4963 : diag::ext_using_attribute_ns);
4965
4966 CommonScopeName = TryParseCXX11AttributeIdentifier(
4968 if (!CommonScopeName) {
4969 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
4971 }
4973 Diag(Tok.getLocation(), diag::err_expected) << tok::colon;
4974 }
4975
4976 bool AttrParsed = false;
4977 while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) {
4978 if (AttrParsed) {
4979
4980
4981 if (ExpectAndConsume(tok::comma)) {
4983 continue;
4984 }
4985 AttrParsed = false;
4986 }
4987
4988
4990 ;
4991
4993 IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;
4994
4995 AttrName = TryParseCXX11AttributeIdentifier(
4997 CommonScopeName);
4998 if (!AttrName)
4999
5000 break;
5001
5002
5004 ScopeName = AttrName;
5005 ScopeLoc = AttrLoc;
5006
5007 AttrName = TryParseCXX11AttributeIdentifier(
5009 ScopeName);
5010 if (!AttrName) {
5011 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5013 continue;
5014 }
5015 }
5016
5017 if (CommonScopeName) {
5018 if (ScopeName) {
5019 Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
5021 } else {
5022 ScopeName = CommonScopeName;
5023 ScopeLoc = CommonScopeLoc;
5024 }
5025 }
5026
5027
5028 if (Tok.is(tok::l_paren))
5029 AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,
5030 ScopeName, ScopeLoc, OpenMPTokens);
5031
5032 if (!AttrParsed) {
5034 AttrName,
5036 ScopeName, ScopeLoc, nullptr, 0,
5038 : ParsedAttr::Form::C23());
5039 AttrParsed = true;
5040 }
5041
5043 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;
5044 }
5045
5046
5047
5048 if (Tok.is(tok::semi)) {
5050 return;
5051 }
5052
5054 if (ExpectAndConsume(tok::r_square))
5056 else if (Tok.is(tok::r_square))
5057 checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);
5058 if (EndLoc)
5060 if (ExpectAndConsume(tok::r_square))
5062}
5063
5064
5065
5066
5067
5071
5072 do {
5073 ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
5074 } while (isAllowedCXX11AttributeSpecifier());
5075
5077}
5078
5079void Parser::DiagnoseAndSkipCXX11Attributes() {
5080 auto Keyword =
5082
5085
5088 (Keyword ? Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword
5089 : Diag(StartLoc, diag::err_attributes_not_allowed))
5091 }
5092}
5093
5096
5097 if (!isCXX11AttributeSpecifier())
5098 return EndLoc;
5099
5100 do {
5101 if (Tok.is(tok::l_square)) {
5103 T.consumeOpen();
5104 T.skipToEnd();
5105 EndLoc = T.getCloseLocation();
5110 } else {
5112 "not an attribute specifier");
5115 if (.consumeOpen())
5116 T.skipToEnd();
5117 EndLoc = T.getCloseLocation();
5118 }
5119 } while (isCXX11AttributeSpecifier());
5120
5121 return EndLoc;
5122}
5123
5124
5125void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
5126 assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list");
5128 assert(UuidIdent->getName() == "uuid" && "Not a Microsoft attribute list");
5129
5132
5133
5135 if (T.consumeOpen()) {
5136 Diag(Tok, diag::err_expected) << tok::l_paren;
5137 return;
5138 }
5139
5141 if (isTokenStringLiteral()) {
5142
5145 return;
5146 ArgExprs.push_back(StringResult.get());
5147 } else {
5148
5149
5150
5151
5152 SmallString<42> StrBuffer;
5153 StrBuffer += "\"";
5154
5155
5156
5157
5158
5159
5160
5161
5163 while (Tok.isNot(tok::r_paren)) {
5165 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
5167 return;
5168 }
5170 SpellingBuffer.resize(Tok.getLength() + 1);
5172 StringRef TokSpelling = PP.getSpelling(Tok, SpellingBuffer, &Invalid);
5173 if (Invalid) {
5175 return;
5176 }
5177 StrBuffer += TokSpelling;
5179 }
5180 StrBuffer += "\"";
5181
5183 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
5184 ConsumeParen();
5185 return;
5186 }
5187
5188
5189
5190
5193 Toks[0].setKind(tok::string_literal);
5196 Toks[0].setLength(StrBuffer.size());
5199 ArgExprs.push_back(UuidString);
5200 }
5201
5202 if (.consumeClose()) {
5203 Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
5205 ParsedAttr::Form::Microsoft());
5206 }
5207}
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {
5218 assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
5219
5222 do {
5223
5225 T.consumeOpen();
5226
5227
5228 while (true) {
5229 SkipUntil(tok::r_square, tok::identifier,
5231 if (Tok.is(tok::code_completion)) {
5232 cutOffParsing();
5236 nullptr);
5237 break;
5238 }
5239 if (Tok.isNot(tok::identifier))
5240 break;
5242 ParseMicrosoftUuidAttributeArgs(Attrs);
5243 else {
5249
5250
5252 bool AttrParsed = false;
5253 if (Tok.is(tok::l_paren)) {
5255 AttrParsed =
5256 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc, nullptr,
5258 ReplayOpenMPAttributeTokens(OpenMPTokens);
5259 }
5260 if (!AttrParsed) {
5262 ParsedAttr::Form::Microsoft());
5263 }
5264 }
5265 }
5266 }
5267
5268 T.consumeClose();
5269 EndLoc = T.getCloseLocation();
5270 } while (Tok.is(tok::l_square));
5271
5273}
5274
5275void Parser::ParseMicrosoftIfExistsClassDeclaration(
5278 IfExistsCondition Result;
5279 if (ParseMicrosoftIfExistsCondition(Result))
5280 return;
5281
5283 if (Braces.consumeOpen()) {
5284 Diag(Tok, diag::err_expected) << tok::l_brace;
5285 return;
5286 }
5287
5288 switch (Result.Behavior) {
5289 case IEB_Parse:
5290
5291 break;
5292
5293 case IEB_Dependent:
5294 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
5295 << Result.IsIfExists;
5296
5297 [[fallthrough]];
5298
5299 case IEB_Skip:
5301 return;
5302 }
5303
5304 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
5305
5306 if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
5307 ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, CurAS);
5308 continue;
5309 }
5310
5311
5312 if (Tok.is(tok::semi)) {
5313 ConsumeExtraSemi(InsideStruct, TagType);
5314 continue;
5315 }
5316
5319
5320 CurAS = AS;
5323 if (Tok.is(tok::colon))
5326 else
5327 Diag(Tok, diag::err_expected) << tok::colon;
5329 continue;
5330 }
5331
5332 ParsedTemplateInfo TemplateInfo;
5333
5334 ParseCXXClassMemberDeclaration(CurAS, AccessAttrs, TemplateInfo);
5335 }
5336
5337 Braces.consumeClose();
5338}
Defines the clang::ASTContext interface.
Defines the C++ template declaration subclasses.
llvm::MachO::RecordLoc RecordLoc
Defines an enumeration for C++ overloaded operators.
static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range, bool IsNoexcept)
static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, IdentifierInfo *ScopeName)
static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr, SourceLocation EndExprLoc)
This file declares facilities that support code completion.
Defines the clang::TokenKind enum and support functions.
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _)
const NestedNameSpecifier * Specifier
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const clang::PrintingPolicy & getPrintingPolicy() const
Attr - This represents one attribute.
Combines information about the source-code form of an attribute, including its syntax and spelling.
@ AS_Microsoft
[uuid("...")] class Foo
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
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.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceRange getRange() const
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Captures information about "declaration specifiers".
void setTypeArgumentRange(SourceRange range)
static const TST TST_typename
void ClearStorageClassSpecs()
TST getTypeSpecType() const
SCS getStorageClassSpec() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceRange getSourceRange() const LLVM_READONLY
void SetPackIndexingExpr(SourceLocation EllipsisLoc, Expr *Pack)
void SetRangeEnd(SourceLocation Loc)
static const TST TST_interface
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_union
static const TST TST_typename_pack_indexing
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool isFriendSpecifiedFirst() const
Expr * getRepAsExpr() const
static const TST TST_decltype
static const TST TST_class
bool hasTagDefinition() const
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
Decl * getRepAsDecl() const
CXXScopeSpec & getTypeSpecScope()
static const TST TST_decltype_auto
void setExternInLinkageSpec(bool Value)
static const TST TST_error
void forEachQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)
This method calls the passed in handler on each qual being set.
FriendSpecified isFriendSpecified() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
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...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
bool isDeclarationOfFunction() const
Determine whether the declaration that will be produced from this declaration will be a function.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
const ParsedAttributes & getAttributes() const
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
void setAsmLabel(Expr *E)
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
A little helper class used to produce diagnostics.
RAII object that enters a new expression evaluation context.
Represents a standard C++ module export declaration.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
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.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
Wrapper for void* pointer.
static OpaquePtr make(PtrTy P)
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
void addAll(iterator B, iterator E)
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void takeAllFrom(ParsedAttributes &Other)
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
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.
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
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.
ExprResult ParseConstantExpression()
ExprResult ParseConditionalExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
const TargetInfo & getTargetInfo() 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 ObjCDeclContextSwitch
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a declarator.
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 AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
SourceManager & getSourceManager() const
bool isBacktrackEnabled() const
True if EnableBacktrackAtThisPos() was called and caching of tokens is on.
void RevertCachedTokens(unsigned N)
When backtracking is enabled and tokens are cached, this allows to revert a specific number of 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 ...
IdentifierTable & getIdentifierTable()
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLastCachedTokenLocation() const
Get the location of the last cached token, suitable for setting the end location of an annotation tok...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ TypeAliasScope
This is a scope of type alias declaration.
@ ClassInheritanceScope
We are between inheritance colon and the real class/struct definition scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ DeclScope
This is a scope that can contain a declaration.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
QualType ProduceCtorInitMemberSignatureHelp(Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, ArrayRef< Expr * > ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteNamespaceAliasDecl(Scope *S)
void CodeCompleteUsing(Scope *S)
void CodeCompleteUsingDirective(Scope *S)
@ PCC_TopLevelOrExpression
Code completion occurs at top-level in a REPL session.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
void CodeCompleteAfterFunctionEquals(Declarator &D)
void CodeCompleteConstructorInitializer(Decl *Constructor, ArrayRef< CXXCtorInitializer * > Initializers)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteNamespaceDecl(Scope *S)
void CodeCompleteTag(Scope *S, unsigned TagSpec)
DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody=nullptr)
Decl * ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, MultiTemplateParamsArg TemplateParams, SourceLocation UsingLoc, UnqualifiedId &Name, const ParsedAttributesView &AttrList, TypeResult Type, Decl *DeclFromDeclSpec)
void PopParsingClass(ParsingClassState state)
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
Decl * ActOnUsingEnumDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation EnumLoc, SourceRange TyLoc, const IdentifierInfo &II, ParsedType Ty, CXXScopeSpec *SS=nullptr)
void ActOnFinishCXXNonNestedClass()
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
void ActOnTagDefinitionError(Scope *S, Decl *TagDecl)
ActOnTagDefinitionError - Invoked when there was an unrecoverable error parsing the definition of a t...
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceRange BraceRange)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, SourceLocation ColonLoc, const ParsedAttributesView &Attrs)
ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
Decl * ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident)
DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, SourceLocation EllipsisLoc, const ParsedAttributesView &Attr, MultiTemplateParamsArg TempParamLists)
Handle a friend tag declaration where the scope specifier was templated.
NamedDecl * ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, InClassInitStyle InitStyle)
ActOnCXXMemberDeclarator - This is invoked when a C++ class member declarator is parsed.
BaseResult ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, const ParsedAttributesView &Attrs, bool Virtual, AccessSpecifier Access, ParsedType basetype, SourceLocation BaseLoc, SourceLocation EllipsisLoc)
ActOnBaseSpecifier - Parsed a base specifier.
bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, const CXXScopeSpec *SS, TemplateTy &SuggestedTemplate, TemplateNameKind &SuggestedKind)
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
NamedDecl * ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ASTContext & getASTContext() const
Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)
We have parsed the start of an export declaration, including the '{' (if present).
ParsingClassState PushParsingClass()
ExprResult ActOnUnevaluatedStringLiteral(ArrayRef< Token > StringToks)
Decl * ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, SourceLocation NamespaceLoc, SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, const ParsedAttributesView &AttrList, UsingDirectiveDecl *&UsingDecl, bool IsNested)
ActOnStartNamespaceDef - This is called at the start of a namespace definition.
SemaCodeCompletion & CodeCompletion()
void ActOnBaseSpecifiers(Decl *ClassDecl, MutableArrayRef< CXXBaseSpecifier * > Bases)
ActOnBaseSpecifiers - Attach the given base specifiers to the class, after checking whether there are...
ExprResult ActOnNoexceptSpec(Expr *NoexceptExpr, ExceptionSpecificationType &EST)
Check the given noexcept-specifier, convert its expression, and compute the appropriate ExceptionSpec...
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
void ProcessDeclAttributeDelayed(Decl *D, const ParsedAttributesView &AttrList)
Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr attribute.
ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr)
void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, SourceLocation FinalLoc, bool IsFinalSpelledSealed, bool IsAbstract, SourceLocation LBraceLoc)
ActOnStartCXXMemberDeclarations - Invoked when we have parsed a C++ record definition's base-specifie...
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.
Decl * ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc, Expr *LangStr, SourceLocation LBraceLoc)
ActOnStartLinkageSpecification - Parsed the beginning of a C++ linkage specification,...
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e....
void ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, ArrayRef< CXXCtorInitializer * > MemInits, bool AnyErrors)
ActOnMemInitializers - Handle the member initializers for a constructor.
TypeResult ActOnTypeName(Declarator &D)
void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, TemplateNameKind &TNK, SourceLocation NameLoc, IdentifierInfo *&II)
Try to resolve an undeclared template name as a type template.
ParsedType getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo &Name)
Handle the result of the special case name lookup for inheriting constructor declarations.
Decl * ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc)
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
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.
void ActOnFinishCXXMemberDecls()
Perform any semantic analysis which needs to be delayed until all pending class member declarations h...
Decl * ActOnFinishLinkageSpecification(Scope *S, Decl *LinkageSpec, SourceLocation RBraceLoc)
ActOnFinishLinkageSpecification - Complete the definition of the C++ linkage specification LinkageSpe...
DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const ParsedAttributesView &Attr)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
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 ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace)
ActOnFinishNamespaceDef - This callback is called after a namespace is exited.
void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context)
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
MemInitResult ActOnMemInitializer(Decl *ConstructorD, Scope *S, CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, ParsedType TemplateTypeTy, const DeclSpec &DS, SourceLocation IdLoc, SourceLocation LParenLoc, ArrayRef< Expr * > Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc)
Handle a C++ member initializer using parentheses syntax.
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)
Complete the definition of an export declaration.
void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc)
SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD)
Invoked when we enter a tag definition that we're skipping.
Decl * ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, SourceLocation NamespcLoc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *NamespcName, const ParsedAttributesView &AttrList)
void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D)
TypeResult ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc)
Parsed an elaborated-type-specifier that refers to a template-id, such as class T::template apply.
Decl * ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation TypenameLoc, CXXScopeSpec &SS, UnqualifiedId &Name, SourceLocation EllipsisLoc, const ParsedAttributesView &AttrList)
ExprResult ActOnDecltypeExpression(Expr *E)
Process the expression contained within a decltype.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Represents a C++ template name within the type system.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
void setLiteralData(const char *Ptr)
SourceLocation getEndLoc() 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
unsigned getLength() const
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
SourceLocation getAnnotationEndLoc() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
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 startToken()
Reset all flags to cleared.
The base class of the type hierarchy.
Represents a C++ unqualified-id that has been parsed.
Represents C++ using-directive.
Declaration of a variable template.
Represents a C++11 virt-specifier-seq.
Specifier getLastSpecifier() const
SourceLocation getFirstLocation() const
SourceLocation getAbstractLoc() const
static const char * getSpecifierName(Specifier VS)
bool SetSpecifier(Specifier VS, SourceLocation Loc, const char *&PrevSpec)
Defines the clang::TargetInfo interface.
@ After
Like System, but searched after the system directories.
bool Zero(InterpState &S, CodePtr OpPC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
constexpr bool isRegularKeywordAttribute(TokenKind K)
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
FunctionDefinitionKind
Described the kind of function definition (if any) provided for a function.
InClassInitStyle
In-class initialization styles for non-static data members.
@ ICIS_CopyInit
Copy initialization.
@ ICIS_ListInit
Direct list-initialization.
@ ICIS_NoInit
No in-class initializer.
bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO)
Return true if the token is a string literal, or a function local predefined macro,...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f.
@ IK_Identifier
An identifier.
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Non_template
The name does not refer to a template.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
const FunctionProtoType * T
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Braces
New-expression has a C++11 list-initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Unparsed
not parsed yet
@ EST_None
no exception specification
@ EST_MSAny
Microsoft throw(...) extension.
@ EST_BasicNoexcept
noexcept
@ EST_Dynamic
throw(T1, T2)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
CachedTokens * ExceptionSpecTokens
Pointer to the cached tokens for an exception-specification that has not yet been parsed.
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.
ExceptionSpecificationType getExceptionSpecType() const
Get the type of exception specification this function has.
std::unique_ptr< CachedTokens > DefaultArgTokens
DefaultArgTokens - When the parameter's default argument cannot be parsed immediately (because it occ...
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.