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.takeAttributesAppendingingFrom(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() {
540 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
541 ++CurTemplateDepthTracker;
543 bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
544 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
559 if (Tok.is(tok::identifier)) {
565 bool MemberOfUnknownSpecialization =
false;
566 auto TNK = Actions.isTemplateName(
568 false, PossibleConceptName,
570 false, PossibleConcept,
571 MemberOfUnknownSpecialization,
573 if (MemberOfUnknownSpecialization || !PossibleConcept ||
576 AnnotateScopeToken(SS, !WasScopeAnnotation);
583 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
592 AnnotateScopeToken(SS, !WasScopeAnnotation);
596NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
597 assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||
598 isTypeConstraintAnnotation()) &&
599 "A type-parameter starts with 'class', 'typename' or a "
602 CXXScopeSpec TypeConstraintSS;
603 TemplateIdAnnotation *TypeConstraint =
nullptr;
604 bool TypenameKeyword =
false;
605 SourceLocation KeyLoc;
606 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
609 if (Tok.is(tok::annot_template_id)) {
612 static_cast<TemplateIdAnnotation *
>(Tok.getAnnotationValue());
614 "stray non-concept template-id annotation");
615 KeyLoc = ConsumeAnnotationToken();
617 assert(TypeConstraintSS.
isEmpty() &&
618 "expected type constraint after scope specifier");
621 TypenameKeyword = Tok.is(tok::kw_typename);
626 SourceLocation EllipsisLoc;
628 DiagCompat(EllipsisLoc, diag_compat::variadic_templates);
632 SourceLocation NameLoc = Tok.getLocation();
633 IdentifierInfo *ParamName =
nullptr;
634 if (Tok.is(tok::identifier)) {
635 ParamName = Tok.getIdentifierInfo();
637 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
638 tok::greatergreater)) {
642 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
647 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
649 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
654 SourceLocation EqualLoc;
656 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
661 DontDestructTemplateIds.emplace(*
this,
true);
666 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
667 ++CurTemplateDepthTracker;
673 NamedDecl *NewDecl = Actions.ActOnTypeParameter(
getCurScope(),
674 TypenameKeyword, EllipsisLoc,
675 KeyLoc, ParamName, NameLoc,
676 Depth, Position, EqualLoc,
678 TypeConstraint !=
nullptr);
680 if (TypeConstraint) {
681 Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
689NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
691 assert(Tok.is(tok::kw_template) &&
"Expected 'template' keyword");
695 SmallVector<NamedDecl*,8> TemplateParams;
696 SourceLocation LAngleLoc, RAngleLoc;
697 ExprResult OptionalRequiresClauseConstraintER;
700 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
701 LAngleLoc, RAngleLoc)) {
705 OptionalRequiresClauseConstraintER =
708 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
709 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
717 SourceLocation NameLoc;
718 IdentifierInfo *ParamName =
nullptr;
719 SourceLocation EllipsisLoc;
720 bool TypenameKeyword =
false;
731 bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
732 const Token &
Next = Tok.is(tok::kw_struct) ?
NextToken() : Tok;
733 if (Tok.is(tok::kw_typename)) {
734 TypenameKeyword =
true;
737 diag_compat::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)
770 DiagCompat(EllipsisLoc, diag_compat::variadic_templates);
773 NameLoc = Tok.getLocation();
774 if (Tok.is(tok::identifier)) {
775 ParamName = Tok.getIdentifierInfo();
777 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
778 tok::greatergreater)) {
782 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
787 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
789 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
791 TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(
792 Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,
793 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
798 SourceLocation EqualLoc;
799 ParsedTemplateArgument DefaultArg;
801 DefaultArg = ParseTemplateTemplateArgument();
803 Diag(Tok.getLocation(),
804 diag::err_default_template_template_parameter_not_template);
805 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
810 return Actions.ActOnTemplateTemplateParameter(
811 getCurScope(), TemplateLoc, Kind, TypenameKeyword, ParamList, EllipsisLoc,
812 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
816Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
820 DeclSpec DS(AttrFactory);
821 ParsedTemplateInfo TemplateInfo;
822 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
823 DeclSpecContext::DSC_template_param);
828 ParseDeclarator(ParamDecl);
830 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
835 SourceLocation EllipsisLoc;
837 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
842 SourceLocation EqualLoc;
844 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
849 DontDestructTemplateIds.emplace(*
this,
true);
850 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
851 Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;
859 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
865 TemplateParameterDepthRAII CurTemplateDepthTracker(
866 TemplateParameterDepth);
867 ++CurTemplateDepthTracker;
868 EnterExpressionEvaluationContext ConstantEvaluated(
870 DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());
877 return Actions.ActOnNonTypeTemplateParameter(
getCurScope(), ParamDecl,
878 Depth, Position, EqualLoc,
884 bool AlreadyHasEllipsis,
885 bool IdentifierHasName) {
887 if (!AlreadyHasEllipsis)
889 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
891 << !IdentifierHasName;
894void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
898 if (!AlreadyHasEllipsis)
901 AlreadyHasEllipsis, D.
hasName());
904bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
906 bool ConsumeLastToken,
907 bool ObjCGenericList) {
910 const char *ReplacementStr =
"> >";
911 bool MergeWithNextToken =
false;
913 switch (Tok.getKind()) {
916 Diag(LAngleLoc, diag::note_matching) << tok::less;
922 RAngleLoc = Tok.getLocation();
923 if (ConsumeLastToken)
927 case tok::greatergreater:
928 RemainingToken = tok::greater;
931 case tok::greatergreatergreater:
932 RemainingToken = tok::greatergreater;
935 case tok::greaterequal:
936 RemainingToken = tok::equal;
937 ReplacementStr =
"> =";
944 RemainingToken = tok::equalequal;
945 MergeWithNextToken =
true;
949 case tok::greatergreaterequal:
950 RemainingToken = tok::greaterequal;
962 SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
963 SourceLocation TokLoc = Tok.getLocation();
969 bool PreventMergeWithNextToken =
970 (RemainingToken == tok::greater ||
971 RemainingToken == tok::greatergreater) &&
972 (
Next.isOneOf(tok::greater, tok::greatergreater,
973 tok::greatergreatergreater, tok::equal, tok::greaterequal,
974 tok::greatergreaterequal, tok::equalequal)) &&
975 areTokensAdjacent(Tok,
Next);
978 if (!ObjCGenericList) {
993 if (PreventMergeWithNextToken)
996 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
998 (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
999 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1000 else if (Tok.is(tok::greaterequal))
1001 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1002 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1013 RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
1016 bool CachingTokens = PP.IsPreviousCachedToken(Tok);
1019 Greater.setLocation(RAngleLoc);
1020 Greater.setKind(tok::greater);
1021 Greater.setLength(GreaterLength);
1023 unsigned OldLength = Tok.getLength();
1024 if (MergeWithNextToken) {
1026 OldLength += Tok.getLength();
1029 Tok.setKind(RemainingToken);
1030 Tok.setLength(OldLength - GreaterLength);
1035 if (PreventMergeWithNextToken)
1036 AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
1037 Tok.setLocation(AfterGreaterLoc);
1040 if (CachingTokens) {
1042 if (MergeWithNextToken)
1043 PP.ReplacePreviousCachedToken({});
1045 if (ConsumeLastToken)
1046 PP.ReplacePreviousCachedToken({
Greater, Tok});
1048 PP.ReplacePreviousCachedToken({
Greater});
1051 if (ConsumeLastToken) {
1052 PrevTokLocation = RAngleLoc;
1054 PrevTokLocation = TokBeforeGreaterLoc;
1055 PP.EnterToken(Tok,
true);
1062bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1064 TemplateArgList &TemplateArgs,
1067 assert(Tok.is(tok::less) &&
"Must have already parsed the template-name");
1073 bool Invalid =
false;
1075 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
1076 if (!Tok.isOneOf(tok::greater, tok::greatergreater,
1077 tok::greatergreatergreater, tok::greaterequal,
1078 tok::greatergreaterequal))
1079 Invalid = ParseTemplateArgumentList(TemplateArgs,
Template, LAngleLoc);
1084 SkipUntil(tok::greater, tok::greatergreater,
1091 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1100 bool AllowTypeAnnotation,
1103 assert((Tok.is(tok::less) || TypeConstraint) &&
1104 "Parser isn't at the beginning of a template-id");
1105 assert(!(TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1106 "a type annotation");
1108 "must accompany a concept name");
1112 SourceLocation TemplateNameLoc =
TemplateName.getSourceRange().getBegin();
1115 SourceLocation LAngleLoc, RAngleLoc;
1116 TemplateArgList TemplateArgs;
1117 bool ArgsInvalid =
false;
1118 if (!TypeConstraint || Tok.is(tok::less)) {
1119 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1120 false, LAngleLoc, TemplateArgs, RAngleLoc,
Template);
1136 : Actions.ActOnTemplateIdType(
1138 SourceLocation(), SS, TemplateKWLoc,
1140 TemplateArgsPtr, RAngleLoc);
1142 Tok.setKind(tok::annot_typename);
1143 setTypeAnnotation(Tok,
Type);
1146 else if (TemplateKWLoc.
isValid())
1147 Tok.setLocation(TemplateKWLoc);
1149 Tok.setLocation(TemplateNameLoc);
1153 Tok.setKind(tok::annot_template_id);
1155 const IdentifierInfo *TemplateII =
1166 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind,
Template, TNK,
1167 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1169 Tok.setAnnotationValue(TemplateId);
1171 Tok.setLocation(TemplateKWLoc);
1173 Tok.setLocation(TemplateNameLoc);
1177 Tok.setAnnotationEndLoc(RAngleLoc);
1181 PP.AnnotateCachedTokens(Tok);
1185void Parser::AnnotateTemplateIdTokenAsType(
1188 assert(Tok.is(tok::annot_template_id) &&
"Requires template-id tokens");
1190 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1192 "Only works for type and dependent templates");
1200 : Actions.ActOnTemplateIdType(
1202 SourceLocation(), SS,
1203 TemplateId->TemplateKWLoc, TemplateId->
Template,
1204 TemplateId->Name, TemplateId->TemplateNameLoc,
1205 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,
1206 false, IsClassName, AllowImplicitTypename);
1208 Tok.setKind(tok::annot_typename);
1209 setTypeAnnotation(Tok,
Type);
1216 PP.AnnotateCachedTokens(Tok);
1222 return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,
1223 tok::greatergreatergreater);
1227 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
1228 !Tok.is(tok::annot_cxxscope) && !Tok.is(tok::annot_template_id) &&
1229 !Tok.is(tok::annot_non_type))
1230 return ParsedTemplateArgument();
1244 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1248 ParsedTemplateArgument
Result;
1249 SourceLocation EllipsisLoc;
1250 if (SS.
isSet() && Tok.is(tok::kw_template)) {
1255 if (Tok.is(tok::identifier)) {
1258 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1268 Actions.ActOnTemplateName(
getCurScope(), SS, TemplateKWLoc, Name,
1274 }
else if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
1275 Tok.is(tok::annot_non_type)) {
1279 bool IsPackIndexingTemplateName =
false;
1280 if (Tok.is(tok::annot_non_type)) {
1281 NamedDecl *ND = getNonTypeAnnotation(Tok);
1285 ConsumeAnnotationToken();
1286 }
else if (Tok.is(tok::annot_template_id)) {
1287 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1293 IsPackIndexingTemplateName =
true;
1296 ConsumeAnnotationToken();
1298 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1305 if (IsPackIndexingTemplateName) {
1306 Result = ParsedTemplateArgument(SourceLocation(), SS,
1309 bool MemberOfUnknownSpecialization;
1314 false,
Template, MemberOfUnknownSpecialization);
1319 Result = ParsedTemplateArgument(SourceLocation(),
1326 Result = Actions.ActOnTemplateTemplateArgument(
Result);
1330 Result = Actions.ActOnPackExpansion(
Result, EllipsisLoc);
1346 EnterExpressionEvaluationContext EnterConstantEvaluated(
1353 return Actions.ActOnTemplateTypeArgument(TypeArg);
1358 TentativeParsingAction TPA(*
this);
1361 ParseTemplateTemplateArgument();
1372 SourceLocation Loc = Tok.getLocation();
1374 ExprArg = ParseBraceInitializer();
1379 return ParsedTemplateArgument();
1383 ExprArg.
get(), Loc);
1386bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1392 auto RunSignatureHelp = [&] {
1395 CalledSignatureHelp =
true;
1396 return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(
1401 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
1402 ParsedTemplateArgument Arg = ParseTemplateArgument();
1403 SourceLocation EllipsisLoc;
1405 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
1408 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1414 TemplateArgs.push_back(Arg);
1428 ParsingDeclRAIIObject
1430 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1431 return ParseDeclarationAfterTemplate(
1432 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1435SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1438 TemplateParams->size());
1440 SourceRange
R(TemplateLoc);
1441 if (ExternLoc.isValid())
1442 R.setBegin(ExternLoc);
1446void Parser::LateTemplateParserCallback(
void *P, LateParsedTemplate &LPT) {
1447 ((
Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1450void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
1455 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1460 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1465 SmallVector<DeclContext*, 4> DeclContextsToReenter;
1466 DeclContext *LexicalTU =
nullptr;
1467 for (DeclContext *DC = FunD; DC; DC = DC->getLexicalParent()) {
1468 if (DC->isTranslationUnit()) {
1472 DeclContextsToReenter.push_back(DC);
1476 LexicalTU = Actions.Context.getTranslationUnitDecl();
1480 Sema::ContextRAII GlobalSavedContext(Actions, LexicalTU);
1483 for (DeclContext *DC : reverse(DeclContextsToReenter)) {
1484 CurTemplateDepthTracker.addDepth(
1489 Actions.PushDeclContext(Actions.getCurScope(), DC);
1494 Sema::FpPragmaStackSaveRAII SavedStack(Actions);
1495 Actions.resetFPOptions(LPT.
FPO);
1497 assert(!LPT.
Toks.empty() &&
"Empty body!");
1501 LPT.
Toks.push_back(Tok);
1502 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1506 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1507 "Inline method not starting with '{', ':' or 'try'");
1517 Actions.ActOnStartOfFunctionDef(
getCurScope(), FunD);
1522 TemplateParameterDepth - 1) &&
1523 "TemplateParameterDepth should be greater than the depth of "
1524 "current template being instantiated!");
1526 ParseFunctionBody(LPT.
D, FnScope);
1527 Actions.UnmarkAsLateParsedTemplate(FunD);
1530void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1532 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1534 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1538 if (
kind == tok::kw_try) {
1539 while (Tok.is(tok::kw_catch)) {
1540 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1541 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1546bool Parser::diagnoseUnknownTemplateId(
ExprResult LHS, SourceLocation
Less) {
1547 TentativeParsingAction TPA(*
this);
1549 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1554 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1555 Actions.diagnoseExprIntendedAsTemplateName(
getCurScope(), LHS,
1566void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1567 assert(Tok.is(tok::less) &&
"not at a potential angle bracket");
1569 bool DependentTemplateName =
false;
1570 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1571 DependentTemplateName))
1583 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1584 Actions.diagnoseExprIntendedAsTemplateName(
1595 TentativeParsingAction TPA(*
this);
1597 if (isTypeIdUnambiguously() &&
1598 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1609 AngleBracketTracker::Priority Priority =
1610 (DependentTemplateName ? AngleBracketTracker::DependentName
1611 : AngleBracketTracker::PotentialTypo) |
1612 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1613 : AngleBracketTracker::NoSpaceBeforeLess);
1614 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.getLocation(),
1618bool Parser::checkPotentialAngleBracketDelimiter(
1623 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1624 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1625 AngleBrackets.clear(*
this);
1632 if (OpToken.
is(tok::greater) && Tok.is(tok::l_paren) &&
1634 Actions.diagnoseExprIntendedAsTemplateName(
1635 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1637 AngleBrackets.clear(*
this);
1643 if (OpToken.
is(tok::greater) ||
1645 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1646 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.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
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 CharNo characters of ...
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
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
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.
PackIndexingTemplateStorage * getAsPackIndexingTemplate() const
Retrieve the pack-index-template-name storage, if any.
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...
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.
Top level wrappers for InstallAPI frontend operations.
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.
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.
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.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
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.