26 return Actions.ActOnReenterTemplateScope(D, [&] {
28 return Actions.getCurScope();
43 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
50 assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&
51 "Token does not start a template declaration.");
81 bool isSpecialization =
true;
82 bool LastParamListWasEmpty =
false;
84 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
88 SourceLocation ExportLoc;
92 SourceLocation TemplateLoc;
94 Diag(Tok.getLocation(), diag::err_expected_template);
99 SourceLocation LAngleLoc, RAngleLoc;
100 SmallVector<NamedDecl*, 4> TemplateParams;
101 if (ParseTemplateParameters(TemplateParamScopes,
102 CurTemplateDepthTracker.getDepth(),
103 TemplateParams, LAngleLoc, RAngleLoc)) {
110 ExprResult OptionalRequiresClauseConstraintER;
111 if (!TemplateParams.empty()) {
112 isSpecialization =
false;
113 ++CurTemplateDepthTracker;
116 OptionalRequiresClauseConstraintER =
119 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
127 LastParamListWasEmpty =
true;
130 ParamLists.push_back(Actions.ActOnTemplateParameterList(
131 CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
132 TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.
get()));
133 }
while (Tok.isOneOf(tok::kw_export, tok::kw_template));
135 ParsedTemplateInfo TemplateInfo(&ParamLists, isSpecialization,
136 LastParamListWasEmpty);
139 if (Tok.is(tok::kw_concept)) {
140 Decl *ConceptDecl = ParseConceptDefinition(TemplateInfo, DeclEnd);
143 ParsingTemplateParams.complete(ConceptDecl);
144 return Actions.ConvertDeclToDeclGroup(ConceptDecl);
147 return ParseDeclarationAfterTemplate(
148 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
153 ParsedAttributes AccessAttrs(AttrFactory);
154 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
163 "Template information required");
165 if (Tok.is(tok::kw_static_assert)) {
167 Diag(Tok.getLocation(), diag::err_templated_invalid_declaration)
168 << TemplateInfo.getSourceRange();
170 return Actions.ConvertDeclToDeclGroup(
171 ParseStaticAssertDeclaration(DeclEnd));
176 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
179 ParsedAttributes DeclAttrs(AttrFactory);
180 ParsedAttributes DeclSpecAttrs(AttrFactory);
186 while (MaybeParseCXX11Attributes(DeclAttrs) ||
187 MaybeParseGNUAttributes(DeclSpecAttrs))
190 if (Tok.is(tok::kw_using))
191 return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
196 ParsingDeclSpec DS(*
this, &DiagsFromTParams);
197 DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
198 DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
199 DS.takeAttributesFrom(DeclSpecAttrs);
201 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
202 getDeclSpecContextFromDeclaratorContext(Context));
204 if (Tok.is(tok::semi)) {
205 ProhibitAttributes(DeclAttrs);
207 RecordDecl *AnonRecord =
nullptr;
208 Decl *
Decl = Actions.ParsedFreeStandingDeclSpec(
210 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
214 Actions.ActOnDefinedDeclarationSpecifier(Decl);
215 assert(!AnonRecord &&
216 "Anonymous unions/structs should not be valid with template");
218 return Actions.ConvertDeclToDeclGroup(Decl);
221 if (DS.hasTagDefinition())
222 Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());
226 ProhibitAttributes(DeclAttrs);
228 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd);
232Parser::ParseConceptDefinition(
const ParsedTemplateInfo &TemplateInfo,
235 "Template information required");
236 assert(Tok.is(tok::kw_concept) &&
237 "ParseConceptDefinition must be called when at a 'concept' keyword");
241 SourceLocation BoolKWLoc;
243 Diag(Tok.getLocation(), diag::err_concept_legacy_bool_keyword) <<
246 DiagnoseAndSkipCXX11Attributes();
249 if (ParseOptionalCXXScopeSpecifier(
253 false,
nullptr,
true) ||
261 diag::err_concept_definition_not_identifier);
275 Diag(
Result.getBeginLoc(), diag::err_concept_definition_not_identifier);
280 const IdentifierInfo *Id =
Result.Identifier;
281 SourceLocation IdLoc =
Result.getBeginLoc();
285 ConceptDecl *D = Actions.ActOnStartConceptDefinition(
286 getCurScope(), *TemplateInfo.TemplateParams, Id, IdLoc);
288 ParsedAttributes Attrs(AttrFactory);
289 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
292 Diag(Tok.getLocation(), diag::err_expected) << tok::equal;
307 DeclEnd = Tok.getLocation();
308 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
309 Expr *ConstraintExpr = ConstraintExprResult.
get();
314 return Actions.ActOnFinishConceptDefinition(
getCurScope(), D, ConstraintExpr,
318bool Parser::ParseTemplateParameters(
319 MultiParseScope &TemplateScopes,
unsigned Depth,
324 Diag(Tok.getLocation(), diag::err_expected_less_after) <<
"template";
331 if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) {
333 Failed = ParseTemplateParameterList(Depth, TemplateParams);
336 if (Tok.is(tok::greatergreater)) {
342 Tok.setKind(tok::greater);
343 RAngleLoc = Tok.getLocation();
344 Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
346 Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
353Parser::ParseTemplateParameterList(
const unsigned Depth,
357 if (NamedDecl *TmpParam
358 = ParseTemplateParameter(Depth, TemplateParams.size())) {
359 TemplateParams.push_back(TmpParam);
363 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
368 if (Tok.is(tok::comma)) {
370 }
else if (Tok.isOneOf(tok::greater, tok::greatergreater)) {
377 Diag(Tok.getLocation(), diag::err_expected_comma_greater);
378 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
386Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
387 if (Tok.is(tok::kw_class)) {
394 case tok::greatergreater:
396 return TPResult::True;
398 case tok::identifier:
404 return TPResult::False;
411 case tok::greatergreater:
412 return TPResult::True;
415 return TPResult::False;
419 if (TryAnnotateTypeConstraint())
420 return TPResult::Error;
422 if (isTypeConstraintAnnotation() &&
427 .
isOneOf(tok::kw_auto, tok::kw_decltype))
428 return TPResult::True;
432 if (Tok.isNot(tok::kw_typename) && Tok.isNot(tok::kw_typedef))
433 return TPResult::False;
444 if (
Next.getKind() == tok::identifier)
447 switch (
Next.getKind()) {
451 case tok::greatergreater:
453 return TPResult::True;
455 case tok::kw_typename:
456 case tok::kw_typedef:
460 return TPResult::True;
463 return TPResult::False;
467NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
469 switch (isStartOfTemplateTypeParameter()) {
473 if (Tok.is(tok::kw_typedef)) {
474 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
476 Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
482 Tok.setKind(tok::kw_typename);
485 return ParseTypeParameter(Depth, Position);
486 case TPResult::False:
489 case TPResult::Error: {
497 DS.SetTypeSpecError();
500 D.SetIdentifier(
nullptr, Tok.getLocation());
501 D.setInvalidType(
true);
502 NamedDecl *ErrorParam = Actions.ActOnNonTypeTemplateParameter(
503 getCurScope(), D, Depth, Position, SourceLocation(),
506 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
511 case TPResult::Ambiguous:
512 llvm_unreachable(
"template param classification can't be ambiguous");
515 if (Tok.is(tok::kw_template))
516 return ParseTemplateTemplateParameter(Depth, Position);
521 return ParseNonTypeTemplateParameter(Depth, Position);
524bool Parser::isTypeConstraintAnnotation() {
525 const Token &
T = Tok.is(tok::annot_cxxscope) ?
NextToken() : Tok;
526 if (
T.isNot(tok::annot_template_id))
528 const auto *ExistingAnnot =
529 static_cast<TemplateIdAnnotation *
>(
T.getAnnotationValue());
533bool Parser::TryAnnotateTypeConstraint() {
537 bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
538 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
553 if (Tok.is(tok::identifier)) {
559 bool MemberOfUnknownSpecialization =
false;
560 auto TNK = Actions.isTemplateName(
getCurScope(), SS,
566 MemberOfUnknownSpecialization,
568 if (MemberOfUnknownSpecialization || !PossibleConcept ||
571 AnnotateScopeToken(SS, !WasScopeAnnotation);
578 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
587 AnnotateScopeToken(SS, !WasScopeAnnotation);
591NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
592 assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||
593 isTypeConstraintAnnotation()) &&
594 "A type-parameter starts with 'class', 'typename' or a "
597 CXXScopeSpec TypeConstraintSS;
598 TemplateIdAnnotation *TypeConstraint =
nullptr;
599 bool TypenameKeyword =
false;
600 SourceLocation KeyLoc;
601 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
604 if (Tok.is(tok::annot_template_id)) {
607 static_cast<TemplateIdAnnotation *
>(Tok.getAnnotationValue());
609 "stray non-concept template-id annotation");
610 KeyLoc = ConsumeAnnotationToken();
612 assert(TypeConstraintSS.
isEmpty() &&
613 "expected type constraint after scope specifier");
616 TypenameKeyword = Tok.is(tok::kw_typename);
621 SourceLocation EllipsisLoc;
625 ? diag::warn_cxx98_compat_variadic_templates
626 : diag::ext_variadic_templates);
630 SourceLocation NameLoc = Tok.getLocation();
631 IdentifierInfo *ParamName =
nullptr;
632 if (Tok.is(tok::identifier)) {
633 ParamName = Tok.getIdentifierInfo();
635 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
636 tok::greatergreater)) {
640 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
645 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
647 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
652 SourceLocation EqualLoc;
654 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
659 DontDestructTemplateIds.emplace(*
this,
true);
664 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
665 ++CurTemplateDepthTracker;
671 NamedDecl *NewDecl = Actions.ActOnTypeParameter(
getCurScope(),
672 TypenameKeyword, EllipsisLoc,
673 KeyLoc, ParamName, NameLoc,
674 Depth, Position, EqualLoc,
676 TypeConstraint !=
nullptr);
678 if (TypeConstraint) {
679 Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
687NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
689 assert(Tok.is(tok::kw_template) &&
"Expected 'template' keyword");
693 SmallVector<NamedDecl*,8> TemplateParams;
694 SourceLocation LAngleLoc, RAngleLoc;
695 ExprResult OptionalRequiresClauseConstraintER;
698 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
699 LAngleLoc, RAngleLoc)) {
703 OptionalRequiresClauseConstraintER =
706 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
707 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
715 SourceLocation NameLoc;
716 IdentifierInfo *ParamName =
nullptr;
717 SourceLocation EllipsisLoc;
718 bool TypenameKeyword =
false;
729 bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
730 const Token &
Next = Tok.is(tok::kw_struct) ?
NextToken() : Tok;
731 if (Tok.is(tok::kw_typename)) {
732 TypenameKeyword =
true;
734 Diag(Tok.getLocation(),
736 ? diag::warn_cxx14_compat_template_template_param_typename
737 : diag::ext_template_template_param_typename)
746 }
else if (
Next.isOneOf(tok::identifier, tok::comma, tok::greater,
747 tok::greatergreater, tok::ellipsis)) {
751 Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
755 : FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
764 Diag(PrevTokLocation, diag::err_cxx26_template_template_params)
772 ? diag::warn_cxx98_compat_variadic_templates
773 : diag::ext_variadic_templates);
776 NameLoc = Tok.getLocation();
777 if (Tok.is(tok::identifier)) {
778 ParamName = Tok.getIdentifierInfo();
780 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
781 tok::greatergreater)) {
785 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
790 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
792 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
794 TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(
795 Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,
796 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
801 SourceLocation EqualLoc;
802 ParsedTemplateArgument DefaultArg;
804 DefaultArg = ParseTemplateTemplateArgument();
806 Diag(Tok.getLocation(),
807 diag::err_default_template_template_parameter_not_template);
808 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
813 return Actions.ActOnTemplateTemplateParameter(
814 getCurScope(), TemplateLoc, Kind, TypenameKeyword, ParamList, EllipsisLoc,
815 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
819Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
823 DeclSpec DS(AttrFactory);
824 ParsedTemplateInfo TemplateInfo;
825 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
826 DeclSpecContext::DSC_template_param);
831 ParseDeclarator(ParamDecl);
833 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
838 SourceLocation EllipsisLoc;
840 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
845 SourceLocation EqualLoc;
848 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
849 Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;
857 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
863 TemplateParameterDepthRAII CurTemplateDepthTracker(
864 TemplateParameterDepth);
865 ++CurTemplateDepthTracker;
866 EnterExpressionEvaluationContext ConstantEvaluated(
868 DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());
875 return Actions.ActOnNonTypeTemplateParameter(
getCurScope(), ParamDecl,
876 Depth, Position, EqualLoc,
882 bool AlreadyHasEllipsis,
883 bool IdentifierHasName) {
885 if (!AlreadyHasEllipsis)
887 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
889 << !IdentifierHasName;
892void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
896 if (!AlreadyHasEllipsis)
899 AlreadyHasEllipsis, D.
hasName());
902bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
904 bool ConsumeLastToken,
905 bool ObjCGenericList) {
908 const char *ReplacementStr =
"> >";
909 bool MergeWithNextToken =
false;
911 switch (Tok.getKind()) {
914 Diag(LAngleLoc, diag::note_matching) << tok::less;
920 RAngleLoc = Tok.getLocation();
921 if (ConsumeLastToken)
925 case tok::greatergreater:
926 RemainingToken = tok::greater;
929 case tok::greatergreatergreater:
930 RemainingToken = tok::greatergreater;
933 case tok::greaterequal:
934 RemainingToken = tok::equal;
935 ReplacementStr =
"> =";
942 RemainingToken = tok::equalequal;
943 MergeWithNextToken =
true;
947 case tok::greatergreaterequal:
948 RemainingToken = tok::greaterequal;
960 SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
961 SourceLocation TokLoc = Tok.getLocation();
967 bool PreventMergeWithNextToken =
968 (RemainingToken == tok::greater ||
969 RemainingToken == tok::greatergreater) &&
970 (
Next.isOneOf(tok::greater, tok::greatergreater,
971 tok::greatergreatergreater, tok::equal, tok::greaterequal,
972 tok::greatergreaterequal, tok::equalequal)) &&
973 areTokensAdjacent(Tok,
Next);
976 if (!ObjCGenericList) {
991 if (PreventMergeWithNextToken)
994 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
996 (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
997 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
998 else if (Tok.is(tok::greaterequal))
999 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1000 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1011 RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
1014 bool CachingTokens = PP.IsPreviousCachedToken(Tok);
1017 Greater.setLocation(RAngleLoc);
1018 Greater.setKind(tok::greater);
1019 Greater.setLength(GreaterLength);
1021 unsigned OldLength = Tok.getLength();
1022 if (MergeWithNextToken) {
1024 OldLength += Tok.getLength();
1027 Tok.setKind(RemainingToken);
1028 Tok.setLength(OldLength - GreaterLength);
1033 if (PreventMergeWithNextToken)
1034 AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
1035 Tok.setLocation(AfterGreaterLoc);
1038 if (CachingTokens) {
1040 if (MergeWithNextToken)
1041 PP.ReplacePreviousCachedToken({});
1043 if (ConsumeLastToken)
1044 PP.ReplacePreviousCachedToken({
Greater, Tok});
1046 PP.ReplacePreviousCachedToken({
Greater});
1049 if (ConsumeLastToken) {
1050 PrevTokLocation = RAngleLoc;
1052 PrevTokLocation = TokBeforeGreaterLoc;
1053 PP.EnterToken(Tok,
true);
1060bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1062 TemplateArgList &TemplateArgs,
1065 assert(Tok.is(tok::less) &&
"Must have already parsed the template-name");
1071 bool Invalid =
false;
1073 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
1074 if (!Tok.isOneOf(tok::greater, tok::greatergreater,
1075 tok::greatergreatergreater, tok::greaterequal,
1076 tok::greatergreaterequal))
1077 Invalid = ParseTemplateArgumentList(TemplateArgs,
Template, LAngleLoc);
1082 SkipUntil(tok::greater, tok::greatergreater,
1089 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1098 bool AllowTypeAnnotation,
1101 assert((Tok.is(tok::less) || TypeConstraint) &&
1102 "Parser isn't at the beginning of a template-id");
1103 assert(!(TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1104 "a type annotation");
1106 "must accompany a concept name");
1110 SourceLocation TemplateNameLoc =
TemplateName.getSourceRange().getBegin();
1113 SourceLocation LAngleLoc, RAngleLoc;
1114 TemplateArgList TemplateArgs;
1115 bool ArgsInvalid =
false;
1116 if (!TypeConstraint || Tok.is(tok::less)) {
1117 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1118 false, LAngleLoc, TemplateArgs, RAngleLoc,
Template);
1134 : Actions.ActOnTemplateIdType(
1136 SourceLocation(), SS, TemplateKWLoc,
1138 TemplateArgsPtr, RAngleLoc);
1140 Tok.setKind(tok::annot_typename);
1141 setTypeAnnotation(Tok,
Type);
1144 else if (TemplateKWLoc.
isValid())
1145 Tok.setLocation(TemplateKWLoc);
1147 Tok.setLocation(TemplateNameLoc);
1151 Tok.setKind(tok::annot_template_id);
1153 const IdentifierInfo *TemplateII =
1164 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind,
Template, TNK,
1165 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1167 Tok.setAnnotationValue(TemplateId);
1169 Tok.setLocation(TemplateKWLoc);
1171 Tok.setLocation(TemplateNameLoc);
1175 Tok.setAnnotationEndLoc(RAngleLoc);
1179 PP.AnnotateCachedTokens(Tok);
1183void Parser::AnnotateTemplateIdTokenAsType(
1186 assert(Tok.is(tok::annot_template_id) &&
"Requires template-id tokens");
1188 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1190 "Only works for type and dependent templates");
1198 : Actions.ActOnTemplateIdType(
1200 SourceLocation(), SS,
1201 TemplateId->TemplateKWLoc, TemplateId->
Template,
1202 TemplateId->Name, TemplateId->TemplateNameLoc,
1203 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,
1204 false, IsClassName, AllowImplicitTypename);
1206 Tok.setKind(tok::annot_typename);
1207 setTypeAnnotation(Tok,
Type);
1214 PP.AnnotateCachedTokens(Tok);
1220 return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,
1221 tok::greatergreatergreater);
1225 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
1226 !Tok.is(tok::annot_cxxscope) && !Tok.is(tok::annot_template_id) &&
1227 !Tok.is(tok::annot_non_type))
1228 return ParsedTemplateArgument();
1242 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1246 ParsedTemplateArgument
Result;
1247 SourceLocation EllipsisLoc;
1248 if (SS.
isSet() && Tok.is(tok::kw_template)) {
1253 if (Tok.is(tok::identifier)) {
1256 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1266 Actions.ActOnTemplateName(
getCurScope(), SS, TemplateKWLoc, Name,
1272 }
else if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
1273 Tok.is(tok::annot_non_type)) {
1277 if (Tok.is(tok::annot_non_type)) {
1278 NamedDecl *ND = getNonTypeAnnotation(Tok);
1282 ConsumeAnnotationToken();
1283 }
else if (Tok.is(tok::annot_template_id)) {
1284 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1288 ConsumeAnnotationToken();
1290 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1297 bool MemberOfUnknownSpecialization;
1302 false,
Template, MemberOfUnknownSpecialization);
1307 Result = ParsedTemplateArgument(SourceLocation(), SS,
1313 Result = Actions.ActOnTemplateTemplateArgument(
Result);
1317 Result = Actions.ActOnPackExpansion(
Result, EllipsisLoc);
1333 EnterExpressionEvaluationContext EnterConstantEvaluated(
1340 return Actions.ActOnTemplateTypeArgument(TypeArg);
1345 TentativeParsingAction TPA(*
this);
1348 ParseTemplateTemplateArgument();
1359 SourceLocation Loc = Tok.getLocation();
1361 ExprArg = ParseBraceInitializer();
1366 return ParsedTemplateArgument();
1370 ExprArg.
get(), Loc);
1373bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1379 auto RunSignatureHelp = [&] {
1382 CalledSignatureHelp =
true;
1383 return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(
1388 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
1389 ParsedTemplateArgument Arg = ParseTemplateArgument();
1390 SourceLocation EllipsisLoc;
1392 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
1395 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1401 TemplateArgs.push_back(Arg);
1415 ParsingDeclRAIIObject
1417 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1418 return ParseDeclarationAfterTemplate(
1419 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1422SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1425 TemplateParams->size());
1427 SourceRange R(TemplateLoc);
1428 if (ExternLoc.isValid())
1429 R.setBegin(ExternLoc);
1433void Parser::LateTemplateParserCallback(
void *P, LateParsedTemplate &LPT) {
1434 ((
Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1437void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
1442 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1447 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1450 Sema::ContextRAII GlobalSavedContext(
1451 Actions, Actions.Context.getTranslationUnitDecl());
1456 SmallVector<DeclContext*, 4> DeclContextsToReenter;
1457 for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();
1458 DC = DC->getLexicalParent())
1459 DeclContextsToReenter.push_back(DC);
1462 for (DeclContext *DC : reverse(DeclContextsToReenter)) {
1463 CurTemplateDepthTracker.addDepth(
1468 Actions.PushDeclContext(Actions.getCurScope(), DC);
1473 Sema::FpPragmaStackSaveRAII SavedStack(Actions);
1474 Actions.resetFPOptions(LPT.
FPO);
1476 assert(!LPT.
Toks.empty() &&
"Empty body!");
1480 LPT.
Toks.push_back(Tok);
1481 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1485 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1486 "Inline method not starting with '{', ':' or 'try'");
1496 Actions.ActOnStartOfFunctionDef(
getCurScope(), FunD);
1498 if (Tok.is(tok::kw_try)) {
1499 ParseFunctionTryBlock(LPT.
D, FnScope);
1501 if (Tok.is(tok::colon))
1502 ParseConstructorInitializer(LPT.
D);
1504 Actions.ActOnDefaultCtorInitializers(LPT.
D);
1506 if (Tok.is(tok::l_brace)) {
1509 ->getTemplateParameters()
1510 ->getDepth() == TemplateParameterDepth - 1) &&
1511 "TemplateParameterDepth should be greater than the depth of "
1512 "current template being instantiated!");
1513 ParseFunctionStatementBody(LPT.
D, FnScope);
1514 Actions.UnmarkAsLateParsedTemplate(FunD);
1516 Actions.ActOnFinishFunctionBody(LPT.
D,
nullptr);
1520void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1522 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1524 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1528 if (kind == tok::kw_try) {
1529 while (Tok.is(tok::kw_catch)) {
1530 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1531 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1536bool Parser::diagnoseUnknownTemplateId(
ExprResult LHS, SourceLocation
Less) {
1537 TentativeParsingAction TPA(*
this);
1539 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1544 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1545 Actions.diagnoseExprIntendedAsTemplateName(
getCurScope(), LHS,
1556void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1557 assert(Tok.is(tok::less) &&
"not at a potential angle bracket");
1559 bool DependentTemplateName =
false;
1560 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1561 DependentTemplateName))
1573 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1574 Actions.diagnoseExprIntendedAsTemplateName(
1585 TentativeParsingAction TPA(*
this);
1587 if (isTypeIdUnambiguously() &&
1588 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1599 AngleBracketTracker::Priority Priority =
1600 (DependentTemplateName ? AngleBracketTracker::DependentName
1601 : AngleBracketTracker::PotentialTypo) |
1602 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1603 : AngleBracketTracker::NoSpaceBeforeLess);
1604 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.getLocation(),
1608bool Parser::checkPotentialAngleBracketDelimiter(
1613 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1614 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1615 AngleBrackets.clear(*
this);
1622 if (OpToken.
is(tok::greater) && Tok.is(tok::l_paren) &&
1624 Actions.diagnoseExprIntendedAsTemplateName(
1625 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1627 AngleBrackets.clear(*
this);
1633 if (OpToken.
is(tok::greater) ||
1635 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1636 AngleBrackets.clear(*
this);
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static bool isEndOfTemplateArgument(Token Tok)
Determine whether the given token can end a template argument.
static constexpr bool isOneOf()
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.
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
static CharSourceRange getCharRange(SourceRange R)
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
static const TST TST_unspecified
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Information about one declarator, including the parsed type information and the identifier.
SourceLocation getIdentifierLoc() const
SourceLocation getEllipsisLoc() const
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
void setEllipsisLoc(SourceLocation EL)
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.
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Characters, const SourceManager &SM, const LangOptions &LangOpts)
AdvanceToTokenCharacter - If the current SourceLocation specifies a location at the start of a token,...
static unsigned getTokenPrefixLength(SourceLocation TokStart, unsigned CharNo, const SourceManager &SM, const LangOptions &LangOpts)
Get the physical length (including trigraphs and escaped newlines) of the first Characters characters...
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Represents the parsed form of a C++ template argument.
@ NonType
A non-type template parameter, stored as an expression.
bool isInvalid() const
Determine whether the given template argument is invalid.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
AttributeFactory & getAttrFactory()
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
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.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
OpaquePtr< TemplateName > TemplateTy
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
friend class ObjCDeclContextSwitch
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
RAII object used to inform the actions that we're currently parsing a declaration.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ DeclScope
This is a scope that can contain a declaration.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
Represents a C++ template name within the type system.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
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)) {....
bool isOneOf(Ts... Ks) const
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
bool isa(CodeGen::Address addr)
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
@ TemplateTemplateArgument
@ IK_Identifier
An identifier.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
@ Type
The name was classified as a type.
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
MutableArrayRef< ParsedTemplateArgument > ASTTemplateArgsPtr
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Non_template
The name does not refer to a template.
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
@ None
The alignment was not explicit in code.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
ActionResult< Expr * > ExprResult
FPOptions FPO
Floating-point options in the point of definition.
Decl * D
The template function declaration to be late parsed.
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.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
bool mightBeType() const
Determine whether this might be a type template.
static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef< ParsedTemplateArgument > TemplateArgs, bool ArgsInvalid, SmallVectorImpl< TemplateIdAnnotation * > &CleanupList)
Creates a new TemplateIdAnnotation with NumArgs arguments and appends it to List.