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 =
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;
630 ? diag::warn_cxx98_compat_variadic_templates
631 : diag::ext_variadic_templates);
635 SourceLocation NameLoc = Tok.getLocation();
636 IdentifierInfo *ParamName =
nullptr;
637 if (Tok.is(tok::identifier)) {
638 ParamName = Tok.getIdentifierInfo();
640 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
641 tok::greatergreater)) {
645 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
650 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
652 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
657 SourceLocation EqualLoc;
659 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
664 DontDestructTemplateIds.emplace(*
this,
true);
669 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
670 ++CurTemplateDepthTracker;
676 NamedDecl *NewDecl = Actions.ActOnTypeParameter(
getCurScope(),
677 TypenameKeyword, EllipsisLoc,
678 KeyLoc, ParamName, NameLoc,
679 Depth, Position, EqualLoc,
681 TypeConstraint !=
nullptr);
683 if (TypeConstraint) {
684 Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
692NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
694 assert(Tok.is(tok::kw_template) &&
"Expected 'template' keyword");
698 SmallVector<NamedDecl*,8> TemplateParams;
699 SourceLocation LAngleLoc, RAngleLoc;
700 ExprResult OptionalRequiresClauseConstraintER;
703 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
704 LAngleLoc, RAngleLoc)) {
708 OptionalRequiresClauseConstraintER =
711 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
712 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
720 SourceLocation NameLoc;
721 IdentifierInfo *ParamName =
nullptr;
722 SourceLocation EllipsisLoc;
723 bool TypenameKeyword =
false;
734 bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
735 const Token &
Next = Tok.is(tok::kw_struct) ?
NextToken() : Tok;
736 if (Tok.is(tok::kw_typename)) {
737 TypenameKeyword =
true;
739 Diag(Tok.getLocation(),
741 ? diag::warn_cxx14_compat_template_template_param_typename
742 : diag::ext_template_template_param_typename)
751 }
else if (
Next.isOneOf(tok::identifier, tok::comma, tok::greater,
752 tok::greatergreater, tok::ellipsis)) {
756 Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
760 : FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
769 Diag(PrevTokLocation, diag::err_cxx26_template_template_params)
777 ? diag::warn_cxx98_compat_variadic_templates
778 : diag::ext_variadic_templates);
781 NameLoc = Tok.getLocation();
782 if (Tok.is(tok::identifier)) {
783 ParamName = Tok.getIdentifierInfo();
785 }
else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
786 tok::greatergreater)) {
790 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
795 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
797 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
799 TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(
800 Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,
801 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
806 SourceLocation EqualLoc;
807 ParsedTemplateArgument DefaultArg;
809 DefaultArg = ParseTemplateTemplateArgument();
811 Diag(Tok.getLocation(),
812 diag::err_default_template_template_parameter_not_template);
813 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
818 return Actions.ActOnTemplateTemplateParameter(
819 getCurScope(), TemplateLoc, Kind, TypenameKeyword, ParamList, EllipsisLoc,
820 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
824Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
828 DeclSpec DS(AttrFactory);
829 ParsedTemplateInfo TemplateInfo;
830 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
831 DeclSpecContext::DSC_template_param);
836 ParseDeclarator(ParamDecl);
838 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
843 SourceLocation EllipsisLoc;
845 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
850 SourceLocation EqualLoc;
853 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
854 Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;
862 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
868 TemplateParameterDepthRAII CurTemplateDepthTracker(
869 TemplateParameterDepth);
870 ++CurTemplateDepthTracker;
871 EnterExpressionEvaluationContext ConstantEvaluated(
873 DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());
880 return Actions.ActOnNonTypeTemplateParameter(
getCurScope(), ParamDecl,
881 Depth, Position, EqualLoc,
887 bool AlreadyHasEllipsis,
888 bool IdentifierHasName) {
890 if (!AlreadyHasEllipsis)
892 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
894 << !IdentifierHasName;
897void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
901 if (!AlreadyHasEllipsis)
904 AlreadyHasEllipsis, D.
hasName());
907bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
909 bool ConsumeLastToken,
910 bool ObjCGenericList) {
913 const char *ReplacementStr =
"> >";
914 bool MergeWithNextToken =
false;
916 switch (Tok.getKind()) {
919 Diag(LAngleLoc, diag::note_matching) << tok::less;
925 RAngleLoc = Tok.getLocation();
926 if (ConsumeLastToken)
930 case tok::greatergreater:
931 RemainingToken = tok::greater;
934 case tok::greatergreatergreater:
935 RemainingToken = tok::greatergreater;
938 case tok::greaterequal:
939 RemainingToken = tok::equal;
940 ReplacementStr =
"> =";
947 RemainingToken = tok::equalequal;
948 MergeWithNextToken =
true;
952 case tok::greatergreaterequal:
953 RemainingToken = tok::greaterequal;
965 SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
966 SourceLocation TokLoc = Tok.getLocation();
972 bool PreventMergeWithNextToken =
973 (RemainingToken == tok::greater ||
974 RemainingToken == tok::greatergreater) &&
975 (
Next.isOneOf(tok::greater, tok::greatergreater,
976 tok::greatergreatergreater, tok::equal, tok::greaterequal,
977 tok::greatergreaterequal, tok::equalequal)) &&
978 areTokensAdjacent(Tok,
Next);
981 if (!ObjCGenericList) {
996 if (PreventMergeWithNextToken)
999 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1001 (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
1002 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1003 else if (Tok.is(tok::greaterequal))
1004 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1005 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1016 RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
1019 bool CachingTokens = PP.IsPreviousCachedToken(Tok);
1022 Greater.setLocation(RAngleLoc);
1023 Greater.setKind(tok::greater);
1024 Greater.setLength(GreaterLength);
1026 unsigned OldLength = Tok.getLength();
1027 if (MergeWithNextToken) {
1029 OldLength += Tok.getLength();
1032 Tok.setKind(RemainingToken);
1033 Tok.setLength(OldLength - GreaterLength);
1038 if (PreventMergeWithNextToken)
1039 AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
1040 Tok.setLocation(AfterGreaterLoc);
1043 if (CachingTokens) {
1045 if (MergeWithNextToken)
1046 PP.ReplacePreviousCachedToken({});
1048 if (ConsumeLastToken)
1049 PP.ReplacePreviousCachedToken({
Greater, Tok});
1051 PP.ReplacePreviousCachedToken({
Greater});
1054 if (ConsumeLastToken) {
1055 PrevTokLocation = RAngleLoc;
1057 PrevTokLocation = TokBeforeGreaterLoc;
1058 PP.EnterToken(Tok,
true);
1065bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1067 TemplateArgList &TemplateArgs,
1070 assert(Tok.is(tok::less) &&
"Must have already parsed the template-name");
1076 bool Invalid =
false;
1078 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
1079 if (!Tok.isOneOf(tok::greater, tok::greatergreater,
1080 tok::greatergreatergreater, tok::greaterequal,
1081 tok::greatergreaterequal))
1082 Invalid = ParseTemplateArgumentList(TemplateArgs,
Template, LAngleLoc);
1087 SkipUntil(tok::greater, tok::greatergreater,
1094 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1103 bool AllowTypeAnnotation,
1106 assert((Tok.is(tok::less) || TypeConstraint) &&
1107 "Parser isn't at the beginning of a template-id");
1108 assert(!(TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1109 "a type annotation");
1111 "must accompany a concept name");
1115 SourceLocation TemplateNameLoc =
TemplateName.getSourceRange().getBegin();
1118 SourceLocation LAngleLoc, RAngleLoc;
1119 TemplateArgList TemplateArgs;
1120 bool ArgsInvalid =
false;
1121 if (!TypeConstraint || Tok.is(tok::less)) {
1122 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1123 false, LAngleLoc, TemplateArgs, RAngleLoc,
Template);
1139 : Actions.ActOnTemplateIdType(
1141 SourceLocation(), SS, TemplateKWLoc,
1143 TemplateArgsPtr, RAngleLoc);
1145 Tok.setKind(tok::annot_typename);
1146 setTypeAnnotation(Tok,
Type);
1149 else if (TemplateKWLoc.
isValid())
1150 Tok.setLocation(TemplateKWLoc);
1152 Tok.setLocation(TemplateNameLoc);
1156 Tok.setKind(tok::annot_template_id);
1158 const IdentifierInfo *TemplateII =
1169 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind,
Template, TNK,
1170 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1172 Tok.setAnnotationValue(TemplateId);
1174 Tok.setLocation(TemplateKWLoc);
1176 Tok.setLocation(TemplateNameLoc);
1180 Tok.setAnnotationEndLoc(RAngleLoc);
1184 PP.AnnotateCachedTokens(Tok);
1188void Parser::AnnotateTemplateIdTokenAsType(
1191 assert(Tok.is(tok::annot_template_id) &&
"Requires template-id tokens");
1193 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1195 "Only works for type and dependent templates");
1203 : Actions.ActOnTemplateIdType(
1205 SourceLocation(), SS,
1206 TemplateId->TemplateKWLoc, TemplateId->
Template,
1207 TemplateId->Name, TemplateId->TemplateNameLoc,
1208 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,
1209 false, IsClassName, AllowImplicitTypename);
1211 Tok.setKind(tok::annot_typename);
1212 setTypeAnnotation(Tok,
Type);
1219 PP.AnnotateCachedTokens(Tok);
1225 return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,
1226 tok::greatergreatergreater);
1230 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
1231 !Tok.is(tok::annot_cxxscope) && !Tok.is(tok::annot_template_id) &&
1232 !Tok.is(tok::annot_non_type))
1233 return ParsedTemplateArgument();
1247 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1251 ParsedTemplateArgument
Result;
1252 SourceLocation EllipsisLoc;
1253 if (SS.
isSet() && Tok.is(tok::kw_template)) {
1258 if (Tok.is(tok::identifier)) {
1261 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1271 Actions.ActOnTemplateName(
getCurScope(), SS, TemplateKWLoc, Name,
1277 }
else if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
1278 Tok.is(tok::annot_non_type)) {
1282 if (Tok.is(tok::annot_non_type)) {
1283 NamedDecl *ND = getNonTypeAnnotation(Tok);
1287 ConsumeAnnotationToken();
1288 }
else if (Tok.is(tok::annot_template_id)) {
1289 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1293 ConsumeAnnotationToken();
1295 Name.
setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1302 bool MemberOfUnknownSpecialization;
1307 false,
Template, MemberOfUnknownSpecialization);
1312 Result = ParsedTemplateArgument(SourceLocation(), SS,
1318 Result = Actions.ActOnTemplateTemplateArgument(
Result);
1322 Result = Actions.ActOnPackExpansion(
Result, EllipsisLoc);
1338 EnterExpressionEvaluationContext EnterConstantEvaluated(
1345 return Actions.ActOnTemplateTypeArgument(TypeArg);
1350 TentativeParsingAction TPA(*
this);
1353 ParseTemplateTemplateArgument();
1364 SourceLocation Loc = Tok.getLocation();
1366 ExprArg = ParseBraceInitializer();
1371 return ParsedTemplateArgument();
1375 ExprArg.
get(), Loc);
1378bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1384 auto RunSignatureHelp = [&] {
1387 CalledSignatureHelp =
true;
1388 return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(
1393 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
1394 ParsedTemplateArgument Arg = ParseTemplateArgument();
1395 SourceLocation EllipsisLoc;
1397 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
1400 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1406 TemplateArgs.push_back(Arg);
1420 ParsingDeclRAIIObject
1422 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1423 return ParseDeclarationAfterTemplate(
1424 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1427SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1430 TemplateParams->size());
1432 SourceRange
R(TemplateLoc);
1433 if (ExternLoc.isValid())
1434 R.setBegin(ExternLoc);
1438void Parser::LateTemplateParserCallback(
void *P, LateParsedTemplate &LPT) {
1439 ((
Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1442void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
1447 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1452 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1455 Sema::ContextRAII GlobalSavedContext(
1456 Actions, Actions.Context.getTranslationUnitDecl());
1461 SmallVector<DeclContext*, 4> DeclContextsToReenter;
1462 for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();
1463 DC = DC->getLexicalParent())
1464 DeclContextsToReenter.push_back(DC);
1467 for (DeclContext *DC : reverse(DeclContextsToReenter)) {
1468 CurTemplateDepthTracker.addDepth(
1473 Actions.PushDeclContext(Actions.getCurScope(), DC);
1478 Sema::FpPragmaStackSaveRAII SavedStack(Actions);
1479 Actions.resetFPOptions(LPT.
FPO);
1481 assert(!LPT.
Toks.empty() &&
"Empty body!");
1485 LPT.
Toks.push_back(Tok);
1486 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1490 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1491 "Inline method not starting with '{', ':' or 'try'");
1501 Actions.ActOnStartOfFunctionDef(
getCurScope(), FunD);
1503 if (Tok.is(tok::kw_try)) {
1504 ParseFunctionTryBlock(LPT.
D, FnScope);
1506 if (Tok.is(tok::colon))
1507 ParseConstructorInitializer(LPT.
D);
1509 Actions.ActOnDefaultCtorInitializers(LPT.
D);
1511 if (Tok.is(tok::l_brace)) {
1514 ->getTemplateParameters()
1515 ->getDepth() == TemplateParameterDepth - 1) &&
1516 "TemplateParameterDepth should be greater than the depth of "
1517 "current template being instantiated!");
1518 ParseFunctionStatementBody(LPT.
D, FnScope);
1519 Actions.UnmarkAsLateParsedTemplate(FunD);
1521 Actions.ActOnFinishFunctionBody(LPT.
D,
nullptr);
1525void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1527 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1529 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1533 if (
kind == tok::kw_try) {
1534 while (Tok.is(tok::kw_catch)) {
1535 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1536 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1541bool Parser::diagnoseUnknownTemplateId(
ExprResult LHS, SourceLocation
Less) {
1542 TentativeParsingAction TPA(*
this);
1544 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1549 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1550 Actions.diagnoseExprIntendedAsTemplateName(
getCurScope(), LHS,
1561void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1562 assert(Tok.is(tok::less) &&
"not at a potential angle bracket");
1564 bool DependentTemplateName =
false;
1565 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1566 DependentTemplateName))
1578 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1579 Actions.diagnoseExprIntendedAsTemplateName(
1590 TentativeParsingAction TPA(*
this);
1592 if (isTypeIdUnambiguously() &&
1593 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1604 AngleBracketTracker::Priority Priority =
1605 (DependentTemplateName ? AngleBracketTracker::DependentName
1606 : AngleBracketTracker::PotentialTypo) |
1607 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1608 : AngleBracketTracker::NoSpaceBeforeLess);
1609 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.getLocation(),
1613bool Parser::checkPotentialAngleBracketDelimiter(
1618 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1619 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1620 AngleBrackets.clear(*
this);
1627 if (OpToken.
is(tok::greater) && Tok.is(tok::l_paren) &&
1629 Actions.diagnoseExprIntendedAsTemplateName(
1630 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1632 AngleBrackets.clear(*
this);
1638 if (OpToken.
is(tok::greater) ||
1640 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1641 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 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)) {....
void * getAnnotationValue() const
bool isOneOf(Ts... Ks) const
bool isNot(tok::TokenKind K) 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.
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
@ 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.