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(
getCurScope(), SS,
572 MemberOfUnknownSpecialization,
574 if (MemberOfUnknownSpecialization || !PossibleConcept ||
577 AnnotateScopeToken(SS, !WasScopeAnnotation);
584 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
593 AnnotateScopeToken(SS, !WasScopeAnnotation);
597NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
598 assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||
599 isTypeConstraintAnnotation()) &&
600 "A type-parameter starts with 'class', 'typename' or a "
603 CXXScopeSpec TypeConstraintSS;
604 TemplateIdAnnotation *TypeConstraint =
nullptr;
605 bool TypenameKeyword =
false;
606 SourceLocation KeyLoc;
607 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
610 if (Tok.is(tok::annot_template_id)) {
613 static_cast<TemplateIdAnnotation *
>(Tok.getAnnotationValue());
615 "stray non-concept template-id annotation");
616 KeyLoc = ConsumeAnnotationToken();
618 assert(TypeConstraintSS.
isEmpty() &&
619 "expected type constraint after scope specifier");
622 TypenameKeyword = Tok.is(tok::kw_typename);
627 SourceLocation EllipsisLoc;
631 ? diag::warn_cxx98_compat_variadic_templates
632 : diag::ext_variadic_templates);
636 SourceLocation NameLoc = Tok.getLocation();
637 IdentifierInfo *ParamName =
nullptr;
638 if (Tok.is(tok::identifier)) {
639 ParamName = Tok.getIdentifierInfo();
641 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
642 tok::greatergreater)) {
646 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
651 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
653 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
658 SourceLocation EqualLoc;
660 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
665 DontDestructTemplateIds.emplace(*
this,
true);
670 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
671 ++CurTemplateDepthTracker;
677 NamedDecl *NewDecl = Actions.ActOnTypeParameter(
getCurScope(),
678 TypenameKeyword, EllipsisLoc,
679 KeyLoc, ParamName, NameLoc,
680 Depth, Position, EqualLoc,
682 TypeConstraint !=
nullptr);
684 if (TypeConstraint) {
685 Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
693NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
695 assert(Tok.is(tok::kw_template) &&
"Expected 'template' keyword");
699 SmallVector<NamedDecl*,8> TemplateParams;
700 SourceLocation LAngleLoc, RAngleLoc;
701 ExprResult OptionalRequiresClauseConstraintER;
704 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
705 LAngleLoc, RAngleLoc)) {
709 OptionalRequiresClauseConstraintER =
712 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
713 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
721 SourceLocation NameLoc;
722 IdentifierInfo *ParamName =
nullptr;
723 SourceLocation EllipsisLoc;
724 bool TypenameKeyword =
false;
735 bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
736 const Token &
Next = Tok.is(tok::kw_struct) ?
NextToken() : Tok;
737 if (Tok.is(tok::kw_typename)) {
738 TypenameKeyword =
true;
740 Diag(Tok.getLocation(),
742 ? diag::warn_cxx14_compat_template_template_param_typename
743 : diag::ext_template_template_param_typename)
752 }
else if (
Next.isOneOf(tok::identifier, tok::comma, tok::greater,
753 tok::greatergreater, tok::ellipsis)) {
757 Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
761 : FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
770 Diag(PrevTokLocation, diag::err_cxx26_template_template_params)
778 ? diag::warn_cxx98_compat_variadic_templates
779 : diag::ext_variadic_templates);
782 NameLoc = Tok.getLocation();
783 if (Tok.is(tok::identifier)) {
784 ParamName = Tok.getIdentifierInfo();
786 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
787 tok::greatergreater)) {
791 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
796 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
798 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
800 TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(
801 Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,
802 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
807 SourceLocation EqualLoc;
808 ParsedTemplateArgument DefaultArg;
810 DefaultArg = ParseTemplateTemplateArgument();
812 Diag(Tok.getLocation(),
813 diag::err_default_template_template_parameter_not_template);
814 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
819 return Actions.ActOnTemplateTemplateParameter(
820 getCurScope(), TemplateLoc, Kind, TypenameKeyword, ParamList, EllipsisLoc,
821 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
825Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
829 DeclSpec DS(AttrFactory);
830 ParsedTemplateInfo TemplateInfo;
831 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
832 DeclSpecContext::DSC_template_param);
837 ParseDeclarator(ParamDecl);
839 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
844 SourceLocation EllipsisLoc;
846 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
851 SourceLocation EqualLoc;
854 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
855 Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;
863 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
869 TemplateParameterDepthRAII CurTemplateDepthTracker(
870 TemplateParameterDepth);
871 ++CurTemplateDepthTracker;
872 EnterExpressionEvaluationContext ConstantEvaluated(
874 DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());
881 return Actions.ActOnNonTypeTemplateParameter(
getCurScope(), ParamDecl,
882 Depth, Position, EqualLoc,
888 bool AlreadyHasEllipsis,
889 bool IdentifierHasName) {
891 if (!AlreadyHasEllipsis)
893 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
895 << !IdentifierHasName;
898void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
902 if (!AlreadyHasEllipsis)
905 AlreadyHasEllipsis, D.
hasName());
908bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
910 bool ConsumeLastToken,
911 bool ObjCGenericList) {
914 const char *ReplacementStr =
"> >";
915 bool MergeWithNextToken =
false;
917 switch (Tok.getKind()) {
920 Diag(LAngleLoc, diag::note_matching) << tok::less;
926 RAngleLoc = Tok.getLocation();
927 if (ConsumeLastToken)
931 case tok::greatergreater:
932 RemainingToken = tok::greater;
935 case tok::greatergreatergreater:
936 RemainingToken = tok::greatergreater;
939 case tok::greaterequal:
940 RemainingToken = tok::equal;
941 ReplacementStr =
"> =";
948 RemainingToken = tok::equalequal;
949 MergeWithNextToken =
true;
953 case tok::greatergreaterequal:
954 RemainingToken = tok::greaterequal;
966 SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
967 SourceLocation TokLoc = Tok.getLocation();
973 bool PreventMergeWithNextToken =
974 (RemainingToken == tok::greater ||
975 RemainingToken == tok::greatergreater) &&
976 (
Next.isOneOf(tok::greater, tok::greatergreater,
977 tok::greatergreatergreater, tok::equal, tok::greaterequal,
978 tok::greatergreaterequal, tok::equalequal)) &&
979 areTokensAdjacent(Tok,
Next);
982 if (!ObjCGenericList) {
997 if (PreventMergeWithNextToken)
1000 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1002 (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
1003 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1004 else if (Tok.is(tok::greaterequal))
1005 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1006 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1017 RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
1020 bool CachingTokens = PP.IsPreviousCachedToken(Tok);
1023 Greater.setLocation(RAngleLoc);
1024 Greater.setKind(tok::greater);
1025 Greater.setLength(GreaterLength);
1027 unsigned OldLength = Tok.getLength();
1028 if (MergeWithNextToken) {
1030 OldLength += Tok.getLength();
1033 Tok.setKind(RemainingToken);
1034 Tok.setLength(OldLength - GreaterLength);
1039 if (PreventMergeWithNextToken)
1040 AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
1041 Tok.setLocation(AfterGreaterLoc);
1044 if (CachingTokens) {
1046 if (MergeWithNextToken)
1047 PP.ReplacePreviousCachedToken({});
1049 if (ConsumeLastToken)
1050 PP.ReplacePreviousCachedToken({
Greater, Tok});
1052 PP.ReplacePreviousCachedToken({
Greater});
1055 if (ConsumeLastToken) {
1056 PrevTokLocation = RAngleLoc;
1058 PrevTokLocation = TokBeforeGreaterLoc;
1059 PP.EnterToken(Tok,
true);
1066bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1068 TemplateArgList &TemplateArgs,
1071 assert(Tok.is(tok::less) &&
"Must have already parsed the template-name");
1077 bool Invalid =
false;
1079 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
1080 if (!Tok.isOneOf(tok::greater, tok::greatergreater,
1081 tok::greatergreatergreater, tok::greaterequal,
1082 tok::greatergreaterequal))
1083 Invalid = ParseTemplateArgumentList(TemplateArgs,
Template, LAngleLoc);
1088 SkipUntil(tok::greater, tok::greatergreater,
1095 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1104 bool AllowTypeAnnotation,
1107 assert((Tok.is(tok::less) || TypeConstraint) &&
1108 "Parser isn't at the beginning of a template-id");
1109 assert(!(TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1110 "a type annotation");
1112 "must accompany a concept name");
1116 SourceLocation TemplateNameLoc =
TemplateName.getSourceRange().getBegin();
1119 SourceLocation LAngleLoc, RAngleLoc;
1120 TemplateArgList TemplateArgs;
1121 bool ArgsInvalid =
false;
1122 if (!TypeConstraint || Tok.is(tok::less)) {
1123 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1124 false, LAngleLoc, TemplateArgs, RAngleLoc,
Template);
1140 : Actions.ActOnTemplateIdType(
1142 SourceLocation(), SS, TemplateKWLoc,
1144 TemplateArgsPtr, RAngleLoc);
1146 Tok.setKind(tok::annot_typename);
1147 setTypeAnnotation(Tok,
Type);
1150 else if (TemplateKWLoc.
isValid())
1151 Tok.setLocation(TemplateKWLoc);
1153 Tok.setLocation(TemplateNameLoc);
1157 Tok.setKind(tok::annot_template_id);
1159 const IdentifierInfo *TemplateII =
1170 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind,
Template, TNK,
1171 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1173 Tok.setAnnotationValue(TemplateId);
1175 Tok.setLocation(TemplateKWLoc);
1177 Tok.setLocation(TemplateNameLoc);
1181 Tok.setAnnotationEndLoc(RAngleLoc);
1185 PP.AnnotateCachedTokens(Tok);
1189void Parser::AnnotateTemplateIdTokenAsType(
1192 assert(Tok.is(tok::annot_template_id) &&
"Requires template-id tokens");
1194 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1196 "Only works for type and dependent templates");
1204 : Actions.ActOnTemplateIdType(
1206 SourceLocation(), SS,
1207 TemplateId->TemplateKWLoc, TemplateId->
Template,
1208 TemplateId->Name, TemplateId->TemplateNameLoc,
1209 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,
1210 false, IsClassName, AllowImplicitTypename);
1212 Tok.setKind(tok::annot_typename);
1213 setTypeAnnotation(Tok,
Type);
1220 PP.AnnotateCachedTokens(Tok);
1226 return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,
1227 tok::greatergreatergreater);
1231 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
1232 !Tok.is(tok::annot_cxxscope) && !Tok.is(tok::annot_template_id) &&
1233 !Tok.is(tok::annot_non_type))
1234 return ParsedTemplateArgument();
1248 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1252 ParsedTemplateArgument
Result;
1253 SourceLocation EllipsisLoc;
1254 if (SS.
isSet() && Tok.is(tok::kw_template)) {
1259 if (Tok.is(tok::identifier)) {
1262 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1272 Actions.ActOnTemplateName(
getCurScope(), SS, TemplateKWLoc, Name,
1278 }
else if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
1279 Tok.is(tok::annot_non_type)) {
1283 if (Tok.is(tok::annot_non_type)) {
1284 NamedDecl *ND = getNonTypeAnnotation(Tok);
1288 ConsumeAnnotationToken();
1289 }
else if (Tok.is(tok::annot_template_id)) {
1290 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1294 ConsumeAnnotationToken();
1296 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1303 bool MemberOfUnknownSpecialization;
1308 false,
Template, MemberOfUnknownSpecialization);
1313 Result = ParsedTemplateArgument(SourceLocation(), SS,
1319 Result = Actions.ActOnTemplateTemplateArgument(
Result);
1323 Result = Actions.ActOnPackExpansion(
Result, EllipsisLoc);
1339 EnterExpressionEvaluationContext EnterConstantEvaluated(
1346 return Actions.ActOnTemplateTypeArgument(TypeArg);
1351 TentativeParsingAction TPA(*
this);
1354 ParseTemplateTemplateArgument();
1365 SourceLocation Loc = Tok.getLocation();
1367 ExprArg = ParseBraceInitializer();
1372 return ParsedTemplateArgument();
1376 ExprArg.
get(), Loc);
1379bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1385 auto RunSignatureHelp = [&] {
1388 CalledSignatureHelp =
true;
1389 return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(
1394 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
1395 ParsedTemplateArgument Arg = ParseTemplateArgument();
1396 SourceLocation EllipsisLoc;
1398 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
1401 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1407 TemplateArgs.push_back(Arg);
1421 ParsingDeclRAIIObject
1423 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1424 return ParseDeclarationAfterTemplate(
1425 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1428SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1431 TemplateParams->size());
1433 SourceRange R(TemplateLoc);
1434 if (ExternLoc.isValid())
1435 R.setBegin(ExternLoc);
1439void Parser::LateTemplateParserCallback(
void *P, LateParsedTemplate &LPT) {
1440 ((
Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1443void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
1448 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1453 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1456 Sema::ContextRAII GlobalSavedContext(
1457 Actions, Actions.Context.getTranslationUnitDecl());
1462 SmallVector<DeclContext*, 4> DeclContextsToReenter;
1463 for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();
1464 DC = DC->getLexicalParent())
1465 DeclContextsToReenter.push_back(DC);
1468 for (DeclContext *DC : reverse(DeclContextsToReenter)) {
1469 CurTemplateDepthTracker.addDepth(
1474 Actions.PushDeclContext(Actions.getCurScope(), DC);
1479 Sema::FpPragmaStackSaveRAII SavedStack(Actions);
1480 Actions.resetFPOptions(LPT.
FPO);
1482 assert(!LPT.
Toks.empty() &&
"Empty body!");
1486 LPT.
Toks.push_back(Tok);
1487 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1491 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1492 "Inline method not starting with '{', ':' or 'try'");
1502 Actions.ActOnStartOfFunctionDef(
getCurScope(), FunD);
1504 if (Tok.is(tok::kw_try)) {
1505 ParseFunctionTryBlock(LPT.
D, FnScope);
1507 if (Tok.is(tok::colon))
1508 ParseConstructorInitializer(LPT.
D);
1510 Actions.ActOnDefaultCtorInitializers(LPT.
D);
1512 if (Tok.is(tok::l_brace)) {
1515 ->getTemplateParameters()
1516 ->getDepth() == TemplateParameterDepth - 1) &&
1517 "TemplateParameterDepth should be greater than the depth of "
1518 "current template being instantiated!");
1519 ParseFunctionStatementBody(LPT.
D, FnScope);
1520 Actions.UnmarkAsLateParsedTemplate(FunD);
1522 Actions.ActOnFinishFunctionBody(LPT.
D,
nullptr);
1526void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1528 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1530 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1534 if (kind == tok::kw_try) {
1535 while (Tok.is(tok::kw_catch)) {
1536 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1537 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1542bool Parser::diagnoseUnknownTemplateId(
ExprResult LHS, SourceLocation
Less) {
1543 TentativeParsingAction TPA(*
this);
1545 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1550 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1551 Actions.diagnoseExprIntendedAsTemplateName(
getCurScope(), LHS,
1562void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1563 assert(Tok.is(tok::less) &&
"not at a potential angle bracket");
1565 bool DependentTemplateName =
false;
1566 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1567 DependentTemplateName))
1579 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1580 Actions.diagnoseExprIntendedAsTemplateName(
1591 TentativeParsingAction TPA(*
this);
1593 if (isTypeIdUnambiguously() &&
1594 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1605 AngleBracketTracker::Priority Priority =
1606 (DependentTemplateName ? AngleBracketTracker::DependentName
1607 : AngleBracketTracker::PotentialTypo) |
1608 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1609 : AngleBracketTracker::NoSpaceBeforeLess);
1610 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.getLocation(),
1614bool Parser::checkPotentialAngleBracketDelimiter(
1619 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1620 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1621 AngleBrackets.clear(*
this);
1628 if (OpToken.
is(tok::greater) && Tok.is(tok::l_paren) &&
1630 Actions.diagnoseExprIntendedAsTemplateName(
1631 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1633 AngleBrackets.clear(*
this);
1639 if (OpToken.
is(tok::greater) ||
1641 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1642 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.