22 #include "llvm/Support/TimeProfiler.h" 23 using namespace clang;
27 Decl *Parser::ParseDeclarationStartingWithTemplate(
34 DeclEnd, AccessAttrs, AS);
36 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
64 Decl *Parser::ParseTemplateDeclarationOrSpecialization(
67 assert(Tok.
isOneOf(tok::kw_export, tok::kw_template) &&
68 "Token does not start a template declaration.");
99 bool isSpecialization =
true;
100 bool LastParamListWasEmpty =
false;
102 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
119 if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
120 TemplateParams, LAngleLoc, RAngleLoc)) {
127 ExprResult OptionalRequiresClauseConstraintER;
128 if (!TemplateParams.empty()) {
129 isSpecialization =
false;
130 ++CurTemplateDepthTracker;
133 OptionalRequiresClauseConstraintER =
137 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
145 LastParamListWasEmpty =
true;
149 CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
150 TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.
get()));
151 }
while (Tok.
isOneOf(tok::kw_export, tok::kw_template));
154 ParseScopeFlags TemplateScopeFlags(
this, NewFlags, isSpecialization);
157 if (Tok.
is(tok::kw_concept))
158 return ParseConceptDefinition(
159 ParsedTemplateInfo(&ParamLists, isSpecialization,
160 LastParamListWasEmpty),
163 return ParseSingleDeclarationAfterTemplate(
165 ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
166 ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
179 Decl *Parser::ParseSingleDeclarationAfterTemplate(
183 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
184 "Template information required");
186 if (Tok.
is(tok::kw_static_assert)) {
189 << TemplateInfo.getSourceRange();
191 return ParseStaticAssertDeclaration(DeclEnd);
196 ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
201 ParsedAttributesWithRange prefixAttrs(AttrFactory);
202 MaybeParseCXX11Attributes(prefixAttrs);
204 if (Tok.
is(tok::kw_using)) {
205 auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
207 if (!usingDeclPtr || !usingDeclPtr.get().isSingleDecl())
209 return usingDeclPtr.get().getSingleDecl();
216 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
217 getDeclSpecContextFromDeclaratorContext(Context));
219 if (Tok.
is(tok::semi)) {
220 ProhibitAttributes(prefixAttrs);
225 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
227 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation,
229 assert(!AnonRecord &&
230 "Anonymous unions/structs should not be valid with template");
236 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
237 ProhibitAttributes(prefixAttrs);
239 DS.takeAttributesFrom(prefixAttrs);
243 if (TemplateInfo.TemplateParams)
244 DeclaratorInfo.setTemplateParameterLists(*TemplateInfo.TemplateParams);
245 ParseDeclarator(DeclaratorInfo);
247 if (!DeclaratorInfo.hasName()) {
250 if (Tok.
is(tok::semi))
255 llvm::TimeTraceScope TimeScope(
"ParseTemplate", [&]() {
256 return DeclaratorInfo.getIdentifier() !=
nullptr 257 ? DeclaratorInfo.getIdentifier()->getName()
261 LateParsedAttrList LateParsedAttrs(
true);
262 if (DeclaratorInfo.isFunctionDeclarator()) {
263 if (Tok.
is(tok::kw_requires))
264 ParseTrailingRequiresClause(DeclaratorInfo);
266 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
269 if (DeclaratorInfo.isFunctionDeclarator() &&
270 isStartOfFunctionDefinition(DeclaratorInfo)) {
276 Diag(Tok, diag::err_function_definition_not_allowed);
285 Diag(DS.getStorageClassSpecLoc(), diag::err_function_declared_typedef)
287 DS.ClearStorageClassSpecs();
290 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
291 if (DeclaratorInfo.getName().getKind() !=
295 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
296 return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(),
301 Diag(DeclaratorInfo.getIdentifierLoc(),
302 diag::err_explicit_instantiation_with_definition)
310 LAngleLoc,
nullptr));
312 return ParseFunctionDefinition(
313 DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists,
319 return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
324 Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
327 if (Tok.
is(tok::comma)) {
328 Diag(Tok, diag::err_multiple_template_declarators)
329 << (int)TemplateInfo.Kind;
335 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
336 if (LateParsedAttrs.size() > 0)
337 ParseLexedAttributeList(LateParsedAttrs, ThisDecl,
true,
false);
338 DeclaratorInfo.complete(ThisDecl);
349 Parser::ParseConceptDefinition(
const ParsedTemplateInfo &TemplateInfo,
351 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
352 "Template information required");
353 assert(Tok.
is(tok::kw_concept) &&
354 "ParseConceptDefinition must be called when at a 'concept' keyword");
363 DiagnoseAndSkipCXX11Attributes();
366 if (ParseOptionalCXXScopeSpecifier(SS,
ParsedType(),
368 false,
nullptr,
true) ||
376 diag::err_concept_definition_not_identifier);
390 Diag(Result.
getBeginLoc(), diag::err_concept_definition_not_identifier);
398 DiagnoseAndSkipCXX11Attributes();
414 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
415 Expr *ConstraintExpr = ConstraintExprResult.
get();
417 *TemplateInfo.TemplateParams,
418 Id, IdLoc, ConstraintExpr);
430 bool Parser::ParseTemplateParameters(
441 if (!Tok.
is(tok::greater) && !Tok.
is(tok::greatergreater))
442 Failed = ParseTemplateParameterList(Depth, TemplateParams);
444 if (Tok.
is(tok::greatergreater)) {
469 Parser::ParseTemplateParameterList(
const unsigned Depth,
474 = ParseTemplateParameter(Depth, TemplateParams.size())) {
475 TemplateParams.push_back(TmpParam);
479 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
484 if (Tok.
is(tok::comma)) {
486 }
else if (Tok.
isOneOf(tok::greater, tok::greatergreater)) {
494 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
504 Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
505 if (Tok.
is(tok::kw_class)) {
512 case tok::greatergreater:
514 return TPResult::True;
516 case tok::identifier:
522 return TPResult::False;
525 switch (GetLookAheadToken(2).
getKind()) {
529 case tok::greatergreater:
530 return TPResult::True;
533 return TPResult::False;
537 if (TryAnnotateTypeConstraint())
538 return TPResult::Error;
540 if (isTypeConstraintAnnotation() &&
544 !GetLookAheadToken(Tok.
is(tok::annot_cxxscope) ? 2 : 1)
545 .
isOneOf(tok::kw_auto, tok::kw_decltype))
546 return TPResult::True;
550 if (Tok.
isNot(tok::kw_typename) && Tok.
isNot(tok::kw_typedef))
551 return TPResult::False;
562 if (Next.
getKind() == tok::identifier)
563 Next = GetLookAheadToken(2);
569 case tok::greatergreater:
571 return TPResult::True;
573 case tok::kw_typename:
574 case tok::kw_typedef:
578 return TPResult::True;
581 return TPResult::False;
605 NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
607 switch (isStartOfTemplateTypeParameter()) {
611 if (Tok.
is(tok::kw_typedef)) {
623 return ParseTypeParameter(Depth, Position);
624 case TPResult::False:
627 case TPResult::Error: {
635 DS.SetTypeSpecError();
638 D.setInvalidType(
true);
643 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
648 case TPResult::Ambiguous:
649 llvm_unreachable(
"template param classification can't be ambiguous");
652 if (Tok.
is(tok::kw_template))
653 return ParseTemplateTemplateParameter(Depth, Position);
658 return ParseNonTypeTemplateParameter(Depth, Position);
663 bool Parser::isTypeConstraintAnnotation() {
665 if (T.
isNot(tok::annot_template_id))
667 const auto *ExistingAnnot =
680 bool Parser::TryAnnotateTypeConstraint() {
684 bool WasScopeAnnotation = Tok.
is(tok::annot_cxxscope);
685 if (ParseOptionalCXXScopeSpecifier(
700 if (Tok.
is(tok::identifier)) {
706 bool MemberOfUnknownSpecialization =
false;
713 MemberOfUnknownSpecialization);
714 if (MemberOfUnknownSpecialization || !PossibleConcept ||
717 AnnotateScopeToken(SS, !WasScopeAnnotation);
724 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
733 AnnotateScopeToken(SS, !WasScopeAnnotation);
746 NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
747 assert((Tok.
isOneOf(tok::kw_class, tok::kw_typename) ||
748 isTypeConstraintAnnotation()) &&
749 "A type-parameter starts with 'class', 'typename' or a " 754 bool TypenameKeyword =
false;
756 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
758 if (Tok.
is(tok::annot_template_id)) {
763 "stray non-concept template-id annotation");
764 KeyLoc = ConsumeAnnotationToken();
766 assert(TypeConstraintSS.
isEmpty() &&
767 "expected type constraint after scope specifier");
770 TypenameKeyword = Tok.
is(tok::kw_typename);
779 ? diag::warn_cxx98_compat_variadic_templates
780 : diag::ext_variadic_templates);
786 if (Tok.
is(tok::identifier)) {
789 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
790 tok::greatergreater)) {
799 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
801 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
814 TypenameKeyword, EllipsisLoc,
815 KeyLoc, ParamName, NameLoc,
816 Depth, Position, EqualLoc,
818 TypeConstraint !=
nullptr);
820 if (TypeConstraint) {
822 cast<TemplateTypeParmDecl>(NewDecl),
841 Parser::ParseTemplateTemplateParameter(
unsigned Depth,
unsigned Position) {
842 assert(Tok.
is(tok::kw_template) &&
"Expected 'template' keyword");
850 if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
862 bool Replace = Tok.
isOneOf(tok::kw_typename, tok::kw_struct);
864 if (Tok.
is(tok::kw_typename)) {
867 ? diag::warn_cxx14_compat_template_template_param_typename
868 : diag::ext_template_template_param_typename)
872 }
else if (Next.
isOneOf(tok::identifier, tok::comma, tok::greater,
873 tok::greatergreater, tok::ellipsis)) {
889 ? diag::warn_cxx98_compat_variadic_templates
890 : diag::ext_variadic_templates);
895 if (Tok.
is(tok::identifier)) {
898 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
899 tok::greatergreater)) {
908 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
910 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
914 TemplateLoc, LAngleLoc,
924 DefaultArg = ParseTemplateTemplateArgument();
927 diag::err_default_template_template_parameter_not_template);
928 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
934 ParamList, EllipsisLoc,
935 ParamName, NameLoc, Depth,
936 Position, EqualLoc, DefaultArg);
946 Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
951 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
AS_none,
952 DeclSpecContext::DSC_template_param);
956 ParseDeclarator(ParamDecl);
965 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
989 Depth, Position, EqualLoc,
993 void Parser::DiagnoseMisplacedEllipsis(
SourceLocation EllipsisLoc,
995 bool AlreadyHasEllipsis,
996 bool IdentifierHasName) {
998 if (!AlreadyHasEllipsis)
1000 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
1002 << !IdentifierHasName;
1005 void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
1007 assert(EllipsisLoc.
isValid());
1009 if (!AlreadyHasEllipsis)
1012 AlreadyHasEllipsis, D.
hasName());
1030 bool Parser::ParseGreaterThanInTemplateList(
SourceLocation &RAngleLoc,
1031 bool ConsumeLastToken,
1032 bool ObjCGenericList) {
1035 const char *ReplacementStr =
"> >";
1036 bool MergeWithNextToken =
false;
1047 if (ConsumeLastToken)
1051 case tok::greatergreater:
1052 RemainingToken = tok::greater;
1055 case tok::greatergreatergreater:
1056 RemainingToken = tok::greatergreater;
1059 case tok::greaterequal:
1060 RemainingToken = tok::equal;
1061 ReplacementStr =
"> =";
1068 RemainingToken = tok::equalequal;
1069 MergeWithNextToken =
true;
1073 case tok::greatergreaterequal:
1074 RemainingToken = tok::greaterequal;
1093 bool PreventMergeWithNextToken =
1094 (RemainingToken == tok::greater ||
1095 RemainingToken == tok::greatergreater) &&
1096 (Next.
isOneOf(tok::greater, tok::greatergreater,
1097 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1098 tok::greatergreaterequal, tok::equalequal)) &&
1099 areTokensAdjacent(Tok, Next);
1102 if (!ObjCGenericList) {
1117 if (PreventMergeWithNextToken)
1120 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1122 (Tok.
is(tok::greatergreater) || Tok.
is(tok::greatergreatergreater)))
1123 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1124 else if (Tok.
is(tok::greaterequal))
1125 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1126 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1137 RAngleLoc = PP.
SplitToken(TokLoc, GreaterLength);
1144 Greater.
setKind(tok::greater);
1148 if (MergeWithNextToken) {
1154 Tok.
setLength(OldLength - GreaterLength);
1159 if (PreventMergeWithNextToken)
1164 if (CachingTokens) {
1166 if (MergeWithNextToken)
1169 if (ConsumeLastToken)
1175 if (ConsumeLastToken) {
1176 PrevTokLocation = RAngleLoc;
1178 PrevTokLocation = TokBeforeGreaterLoc;
1199 Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1201 TemplateArgList &TemplateArgs,
1203 assert(Tok.
is(tok::less) &&
"Must have already parsed the template-name");
1212 if (!Tok.
isOneOf(tok::greater, tok::greatergreater,
1213 tok::greatergreatergreater, tok::greaterequal,
1214 tok::greatergreaterequal))
1215 Invalid = ParseTemplateArgumentList(TemplateArgs);
1219 if (ConsumeLastToken)
1227 return ParseGreaterThanInTemplateList(RAngleLoc, ConsumeLastToken,
1276 bool AllowTypeAnnotation,
1277 bool TypeConstraint) {
1279 assert(Template && (Tok.
is(tok::less) || TypeConstraint) &&
1280 "Parser isn't at the beginning of a template-id");
1281 assert(!(TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be " 1282 "a type annotation");
1284 "must accompany a concept name");
1291 TemplateArgList TemplateArgs;
1292 if (!TypeConstraint || Tok.
is(tok::less)) {
1293 bool Invalid = ParseTemplateIdAfterTemplateName(
false, LAngleLoc,
1313 TemplateNameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc);
1324 Tok.
setKind(tok::annot_typename);
1325 setTypeAnnotation(Tok, Type.
get());
1328 else if (TemplateKWLoc.
isValid())
1335 Tok.
setKind(tok::annot_template_id);
1348 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1349 LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
1380 void Parser::AnnotateTemplateIdTokenAsType(
CXXScopeSpec &SS,
1382 assert(Tok.
is(tok::annot_template_id) &&
"Requires template-id tokens");
1388 "Only works for type and dependent templates");
1391 TemplateId->NumArgs);
1396 TemplateId->TemplateKWLoc,
1397 TemplateId->Template,
1399 TemplateId->TemplateNameLoc,
1400 TemplateId->LAngleLoc,
1402 TemplateId->RAngleLoc,
1406 Tok.
setKind(tok::annot_typename);
1407 setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get());
1419 return Tok.
isOneOf(tok::comma, tok::greater, tok::greatergreater);
1424 if (!Tok.
is(tok::identifier) && !Tok.
is(tok::coloncolon) &&
1425 !Tok.
is(tok::annot_cxxscope))
1440 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1445 if (SS.
isSet() && Tok.
is(tok::kw_template)) {
1450 if (Tok.
is(tok::identifier)) {
1469 }
else if (Tok.
is(tok::identifier)) {
1479 bool MemberOfUnknownSpecialization;
1484 false, Template, MemberOfUnknownSpecialization);
1521 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1529 TentativeParsingAction TPA(*
this);
1532 = ParseTemplateTemplateArgument();
1533 if (!TemplateTemplateArgument.
isInvalid()) {
1535 return TemplateTemplateArgument;
1550 ExprArg.
get(), Loc);
1560 Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
1576 TemplateArgs.push_back(Arg);
1602 return ParseSingleDeclarationAfterTemplate(
1603 Context, ParsedTemplateInfo(ExternLoc, TemplateLoc),
1604 ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1610 TemplateParams->size());
1614 R.setBegin(ExternLoc);
1619 ((
Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1630 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1642 struct ContainingDC {
1643 ContainingDC(
DeclContext *DC,
bool ShouldPush) : Pair(DC, ShouldPush) {}
1644 llvm::PointerIntPair<DeclContext *, 1, bool> Pair;
1645 DeclContext *getDC() {
return Pair.getPointer(); }
1646 bool shouldPushDC() {
return Pair.getInt(); }
1650 DeclContext *NextContaining = Actions.getContainingDC(DD);
1652 bool ShouldPush = DD == NextContaining;
1653 DeclContextsToReenter.push_back({DD, ShouldPush});
1655 NextContaining = Actions.getContainingDC(DD);
1660 for (ContainingDC CDC : reverse(DeclContextsToReenter)) {
1661 TemplateParamScopeStack.push_back(
1663 unsigned NumParamLists = Actions.ActOnReenterTemplateScope(
1665 CurTemplateDepthTracker.addDepth(NumParamLists);
1666 if (CDC.shouldPushDC()) {
1668 Actions.PushDeclContext(Actions.getCurScope(), CDC.getDC());
1672 assert(!LPT.
Toks.empty() &&
"Empty body!");
1676 LPT.
Toks.push_back(Tok);
1677 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1681 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1682 "Inline method not starting with '{', ':' or 'try'");
1691 Actions.getContainingDC(FunD));
1693 Actions.ActOnStartOfFunctionDef(
getCurScope(), FunD);
1695 if (Tok.
is(tok::kw_try)) {
1696 ParseFunctionTryBlock(LPT.
D, FnScope);
1698 if (Tok.
is(tok::colon))
1699 ParseConstructorInitializer(LPT.
D);
1701 Actions.ActOnDefaultCtorInitializers(LPT.
D);
1703 if (Tok.
is(tok::l_brace)) {
1704 assert((!isa<FunctionTemplateDecl>(LPT.
D) ||
1705 cast<FunctionTemplateDecl>(LPT.
D)
1706 ->getTemplateParameters()
1707 ->getDepth() == TemplateParameterDepth - 1) &&
1708 "TemplateParameterDepth should be greater than the depth of " 1709 "current template being instantiated!");
1710 ParseFunctionStatementBody(LPT.
D, FnScope);
1711 Actions.UnmarkAsLateParsedTemplate(FunD);
1713 Actions.ActOnFinishFunctionBody(LPT.
D,
nullptr);
1719 TemplateParamScopeStack.rbegin();
1720 for (; I != TemplateParamScopeStack.rend(); ++I)
1725 void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1727 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1729 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1733 if (kind == tok::kw_try) {
1734 while (Tok.
is(tok::kw_catch)) {
1735 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1736 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1746 TentativeParsingAction TPA(*
this);
1748 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1753 ParseGreaterThanInTemplateList(Greater,
true,
false);
1754 Actions.diagnoseExprIntendedAsTemplateName(
getCurScope(), LHS,
1765 void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1766 assert(Tok.
is(tok::less) &&
"not at a potential angle bracket");
1769 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1770 DependentTemplateName))
1782 ParseGreaterThanInTemplateList(Greater,
true,
false);
1783 Actions.diagnoseExprIntendedAsTemplateName(
1784 getCurScope(), PotentialTemplateName, Less, Greater);
1794 TentativeParsingAction TPA(*
this);
1796 if (isTypeIdUnambiguously() &&
1797 diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {
1809 (DependentTemplateName ? AngleBracketTracker::DependentName
1810 : AngleBracketTracker::PotentialTypo) |
1811 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1812 : AngleBracketTracker::NoSpaceBeforeLess);
1813 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.getLocation(),
1817 bool Parser::checkPotentialAngleBracketDelimiter(
1818 const AngleBracketTracker::Loc &LAngle,
const Token &OpToken) {
1822 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1823 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1824 AngleBrackets.clear(*
this);
1831 if (OpToken.
is(tok::greater) && Tok.
is(tok::l_paren) &&
1833 Actions.diagnoseExprIntendedAsTemplateName(
1834 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1836 AngleBrackets.clear(*
this);
1842 if (OpToken.
is(tok::greater) ||
1844 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1845 AngleBrackets.clear(*
this);
Defines the clang::ASTContext interface.
void ReplacePreviousCachedToken(ArrayRef< Token > NewToks)
Replace token in CachedLexPos - 1 in CachedTokens by the tokens in NewToks.
Represents a function declaration or definition.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
IdentifierInfo * Identifier
When Kind == IK_Identifier, the parsed identifier, or when Kind == IK_UserLiteralId, the identifier suffix.
TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool &MemberOfUnknownSpecialization)
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)) {...
The name refers to a dependent template name:
bool isEmpty() const
No scope specifier.
Decl - This represents one declaration (or definition), e.g.
RAII object used to inform the actions that we're currently parsing a declaration.
Defines the C++ template declaration subclasses.
The base class of the type hierarchy.
This indicates that the scope corresponds to a function, which means that labels are set here...
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
TemplateNameKind Kind
The kind of template that Template refers to.
Parser - This implements a parser for the C family of languages.
RAII object that enters a new expression evaluation context.
Information about one declarator, including the parsed type information and the identifier.
Stores a list of template parameters for a TemplateDecl and its derived classes.
friend class ObjCDeclContextSwitch
Defines the clang::Expr interface and subclasses for C++ expressions.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
tok::TokenKind getKind() const
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 ...
Information about a template-id annotation token.
Represents a struct/union/class.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
bool TryConsumeToken(tok::TokenKind Expected)
One of these records is kept for each identifier that is lexed.
Lookup for the name failed, but we're assuming it was a template name anyway.
Represents a dependent template name that cannot be resolved prior to template instantiation.
OverloadedOperatorKind Operator
The kind of overloaded operator.
struct OFI OperatorFunctionId
When Kind == IK_OperatorFunctionId, the overloaded operator that we parsed.
Token - This structure provides full information about a lexed token.
A non-type template parameter, stored as an expression.
void setKind(tok::TokenKind K)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
NamedDecl * ActOnTemplateTemplateParameter(Scope *S, SourceLocation TmpLoc, TemplateParameterList *Params, SourceLocation EllipsisLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, unsigned Depth, unsigned Position, SourceLocation EqualLoc, ParsedTemplateArgument DefaultArg)
ActOnTemplateTemplateParameter - Called when a C++ template template parameter (e.g.
Represents a C++ unqualified-id that has been parsed.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Scope - A scope is a transient data structure that is used while parsing the program.
bool IsPreviousCachedToken(const Token &Tok) const
Whether Tok is the most recent token (CachedLexPos - 1) in CachedTokens.
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...
Represents a C++ nested-name-specifier or a global scope specifier.
static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef< ParsedTemplateArgument > TemplateArgs, SmallVectorImpl< TemplateIdAnnotation *> &CleanupList)
Creates a new TemplateIdAnnotation with NumArgs arguments and appends it to List. ...
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type...
AttributeFactory & getAttrFactory()
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
unsigned getFlags() const
getFlags - Return the flags for this scope.
SourceLocation getBeginLoc() const LLVM_READONLY
A class for parsing a declarator.
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl *> Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
void setAnnotationValue(void *val)
This represents one expression.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e...
Represents a character-granular source range.
void AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
This file defines the classes used to store parsed information about declaration-specifiers and decla...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, ParsedType ObjectType, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
The name refers to a concept.
OpaquePtr< TemplateName > TemplateTy
static constexpr bool isOneOf()
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
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...
SourceLocation getBeginLoc() const
static bool isEndOfTemplateArgument(Token Tok)
Determine whether the given token can end a template argument.
Represents a C++ template name within the type system.
This is a compound statement scope.
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
void setEllipsisLoc(SourceLocation EL)
The result type of a method or function.
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion...
RAII object that makes '>' behave either as an operator or as the closing angle bracket for a templat...
const LangOptions & getLangOpts() const
static CharSourceRange getCharRange(SourceRange R)
SourceManager & getSourceManager() const
A class for parsing a DeclSpec.
Stop skipping at semicolon.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Represents the parsed form of a C++ template argument.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
Encodes a location in the source.
void setLength(unsigned Len)
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
NamedDecl * ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, SourceLocation EqualLoc, Expr *DefaultArg)
TemplateNameKind ActOnDependentTemplateName(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool AllowInjectedClassName=false)
Form a dependent template name.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
Scope * getCurScope() const
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
bool isInvalid() const
An error occurred during parsing of the scope specifier.
TypeResult ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, IdentifierInfo *TemplateII, SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, bool IsCtorOrDtorName=false, bool IsClassName=false)
bool isNot(tok::TokenKind K) const
SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length)
Split the first Length characters out of the token starting at TokLoc and return a location pointing ...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
This is a scope that corresponds to the template parameters of a C++ template.
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
bool isInvalid() const
Determine whether the given template argument is invalid.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
The name refers to a template whose specialization produces a type.
static const TST TST_unspecified
unsigned getLength() const
Not an overloaded operator.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
ParsedTemplateArgument ActOnTemplateTypeArgument(TypeResult ParsedType)
Convert a parsed type into a parsed template argument.
bool ActOnTypeConstraint(const CXXScopeSpec &SS, TemplateIdAnnotation *TypeConstraint, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc)
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
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.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
This is a scope that can contain a declaration.
NamedDecl * ActOnTypeParameter(Scope *S, bool Typename, SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, unsigned Depth, unsigned Position, SourceLocation EqualLoc, ParsedType DefaultArg, bool HasTypeConstraint)
ActOnTypeParameter - Called when a C++ template type parameter (e.g., "typename T") has been parsed...
SourceLocation getIdentifierLoc() const
bool isSet() const
Deprecated.
TranslationUnitDecl * getTranslationUnitDecl() const
Captures information about "declaration specifiers".
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
SourceLocation getEllipsisLoc() const
Decl * D
The template function declaration to be late parsed.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
A template-id, e.g., f<int>.
Contains a late templated function.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
bool isTranslationUnit() const
Decl * ActOnConceptDefinition(Scope *S, MultiTemplateParamsArg TemplateParameterLists, IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr)
void * getAnnotationValue() const
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
Stop skipping at specified token, but don't skip the token itself.
SourceLocation getEndLoc() const