24#include "llvm/Support/TimeProfiler.h"
43 ObjCDeclContextSwitch ObjCDC(*
this);
45 if (Tok.
is(tok::kw_template) &&
NextToken().isNot(tok::less)) {
50 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
81 assert(Tok.
isOneOf(tok::kw_export, tok::kw_template) &&
82 "Token does not start a template declaration.");
84 MultiParseScope TemplateParamScopes(*
this);
112 bool isSpecialization =
true;
113 bool LastParamListWasEmpty =
false;
115 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
132 if (ParseTemplateParameters(TemplateParamScopes,
133 CurTemplateDepthTracker.getDepth(),
134 TemplateParams, LAngleLoc, RAngleLoc)) {
141 ExprResult OptionalRequiresClauseConstraintER;
142 if (!TemplateParams.empty()) {
143 isSpecialization =
false;
144 ++CurTemplateDepthTracker;
147 OptionalRequiresClauseConstraintER =
150 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
158 LastParamListWasEmpty =
true;
162 CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
163 TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.
get()));
164 }
while (Tok.
isOneOf(tok::kw_export, tok::kw_template));
166 ParsedTemplateInfo TemplateInfo(&ParamLists, isSpecialization,
167 LastParamListWasEmpty);
170 if (Tok.
is(tok::kw_concept))
172 ParseConceptDefinition(TemplateInfo, DeclEnd));
174 return ParseDeclarationAfterTemplate(
175 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
192 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
193 "Template information required");
195 if (Tok.
is(tok::kw_static_assert)) {
198 << TemplateInfo.getSourceRange();
201 ParseStaticAssertDeclaration(DeclEnd));
206 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
216 while (MaybeParseCXX11Attributes(DeclAttrs) ||
217 MaybeParseGNUAttributes(DeclSpecAttrs))
220 if (Tok.
is(tok::kw_using))
221 return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
227 DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
228 DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
229 DS.takeAttributesFrom(DeclSpecAttrs);
231 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
232 getDeclSpecContextFromDeclaratorContext(Context));
234 if (Tok.
is(tok::semi)) {
235 ProhibitAttributes(DeclAttrs);
240 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
242 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation,
245 assert(!AnonRecord &&
246 "Anonymous unions/structs should not be valid with template");
251 if (DS.hasTagDefinition())
255 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
256 ProhibitAttributes(DeclAttrs);
258 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd);
268Parser::ParseConceptDefinition(
const ParsedTemplateInfo &TemplateInfo,
270 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
271 "Template information required");
272 assert(Tok.
is(tok::kw_concept) &&
273 "ParseConceptDefinition must be called when at a 'concept' keyword");
282 DiagnoseAndSkipCXX11Attributes();
285 if (ParseOptionalCXXScopeSpecifier(
289 false,
nullptr,
true) ||
297 diag::err_concept_definition_not_identifier);
311 Diag(
Result.getBeginLoc(), diag::err_concept_definition_not_identifier);
319 DiagnoseAndSkipCXX11Attributes();
335 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
336 Expr *ConstraintExpr = ConstraintExprResult.
get();
338 *TemplateInfo.TemplateParams,
339 Id, IdLoc, ConstraintExpr);
351bool Parser::ParseTemplateParameters(
352 MultiParseScope &TemplateScopes,
unsigned Depth,
364 if (!Tok.
is(tok::greater) && !Tok.
is(tok::greatergreater)) {
366 Failed = ParseTemplateParameterList(Depth, TemplateParams);
369 if (Tok.
is(tok::greatergreater)) {
394Parser::ParseTemplateParameterList(
const unsigned Depth,
399 = ParseTemplateParameter(Depth, TemplateParams.size())) {
400 TemplateParams.push_back(TmpParam);
404 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
409 if (Tok.
is(tok::comma)) {
411 }
else if (Tok.
isOneOf(tok::greater, tok::greatergreater)) {
419 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
429Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
430 if (Tok.
is(tok::kw_class)) {
437 case tok::greatergreater:
439 return TPResult::True;
441 case tok::identifier:
447 return TPResult::False;
450 switch (GetLookAheadToken(2).
getKind()) {
454 case tok::greatergreater:
455 return TPResult::True;
458 return TPResult::False;
462 if (TryAnnotateTypeConstraint())
463 return TPResult::Error;
465 if (isTypeConstraintAnnotation() &&
469 !GetLookAheadToken(Tok.
is(tok::annot_cxxscope) ? 2 : 1)
470 .
isOneOf(tok::kw_auto, tok::kw_decltype))
471 return TPResult::True;
475 if (Tok.
isNot(tok::kw_typename) && Tok.
isNot(tok::kw_typedef))
476 return TPResult::False;
487 if (Next.getKind() == tok::identifier)
488 Next = GetLookAheadToken(2);
490 switch (Next.getKind()) {
494 case tok::greatergreater:
496 return TPResult::True;
498 case tok::kw_typename:
499 case tok::kw_typedef:
503 return TPResult::True;
506 return TPResult::False;
530NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
532 switch (isStartOfTemplateTypeParameter()) {
536 if (Tok.
is(tok::kw_typedef)) {
548 return ParseTypeParameter(Depth, Position);
549 case TPResult::False:
552 case TPResult::Error: {
560 DS.SetTypeSpecError();
564 D.setInvalidType(
true);
569 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
574 case TPResult::Ambiguous:
575 llvm_unreachable(
"template param classification can't be ambiguous");
578 if (Tok.
is(tok::kw_template))
579 return ParseTemplateTemplateParameter(Depth, Position);
584 return ParseNonTypeTemplateParameter(Depth, Position);
589bool Parser::isTypeConstraintAnnotation() {
591 if (
T.isNot(tok::annot_template_id))
593 const auto *ExistingAnnot =
606bool Parser::TryAnnotateTypeConstraint() {
610 bool WasScopeAnnotation = Tok.
is(tok::annot_cxxscope);
611 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
626 if (Tok.
is(tok::identifier)) {
632 bool MemberOfUnknownSpecialization =
false;
639 MemberOfUnknownSpecialization,
641 if (MemberOfUnknownSpecialization || !PossibleConcept ||
644 AnnotateScopeToken(SS, !WasScopeAnnotation);
651 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
660 AnnotateScopeToken(SS, !WasScopeAnnotation);
673NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
674 assert((Tok.
isOneOf(tok::kw_class, tok::kw_typename) ||
675 isTypeConstraintAnnotation()) &&
676 "A type-parameter starts with 'class', 'typename' or a "
681 bool TypenameKeyword =
false;
683 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
686 if (Tok.
is(tok::annot_template_id)) {
691 "stray non-concept template-id annotation");
692 KeyLoc = ConsumeAnnotationToken();
694 assert(TypeConstraintSS.
isEmpty() &&
695 "expected type constraint after scope specifier");
698 TypenameKeyword = Tok.
is(tok::kw_typename);
707 ? diag::warn_cxx98_compat_variadic_templates
708 : diag::ext_variadic_templates);
714 if (Tok.
is(tok::identifier)) {
717 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
718 tok::greatergreater)) {
727 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
729 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
736 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
741 DontDestructTemplateIds.emplace(*
this,
true);
746 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
747 ++CurTemplateDepthTracker;
754 TypenameKeyword, EllipsisLoc,
755 KeyLoc, ParamName, NameLoc,
756 Depth, Position, EqualLoc,
762 cast<TemplateTypeParmDecl>(NewDecl),
781NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
783 assert(Tok.
is(tok::kw_template) &&
"Expected 'template' keyword");
789 ExprResult OptionalRequiresClauseConstraintER;
791 MultiParseScope TemplateParmScope(*
this);
792 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
793 LAngleLoc, RAngleLoc)) {
797 OptionalRequiresClauseConstraintER =
800 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
801 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
813 bool TypenameKeyword =
false;
815 bool Replace = Tok.
isOneOf(tok::kw_typename, tok::kw_struct);
817 if (Tok.
is(tok::kw_typename)) {
818 TypenameKeyword =
true;
821 ? diag::warn_cxx14_compat_template_template_param_typename
822 : diag::ext_template_template_param_typename)
826 }
else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
827 tok::greatergreater, tok::ellipsis)) {
832 :
FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
846 ? diag::warn_cxx98_compat_variadic_templates
847 : diag::ext_variadic_templates);
852 if (Tok.
is(tok::identifier)) {
855 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
856 tok::greatergreater)) {
865 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
867 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
871 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
879 DefaultArg = ParseTemplateTemplateArgument();
882 diag::err_default_template_template_parameter_not_template);
883 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
889 getCurScope(), TemplateLoc, ParamList, TypenameKeyword, EllipsisLoc,
890 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
900Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
905 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
AS_none,
906 DeclSpecContext::DSC_template_param);
911 ParseDeclarator(ParamDecl);
920 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
928 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
943 TemplateParameterDepthRAII CurTemplateDepthTracker(
944 TemplateParameterDepth);
945 ++CurTemplateDepthTracker;
956 Depth, Position, EqualLoc,
962 bool AlreadyHasEllipsis,
963 bool IdentifierHasName) {
965 if (!AlreadyHasEllipsis)
967 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
969 << !IdentifierHasName;
972void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
976 if (!AlreadyHasEllipsis)
979 AlreadyHasEllipsis, D.
hasName());
997bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
999 bool ConsumeLastToken,
1000 bool ObjCGenericList) {
1003 const char *ReplacementStr =
"> >";
1004 bool MergeWithNextToken =
false;
1009 Diag(LAngleLoc, diag::note_matching) << tok::less;
1016 if (ConsumeLastToken)
1020 case tok::greatergreater:
1021 RemainingToken = tok::greater;
1024 case tok::greatergreatergreater:
1025 RemainingToken = tok::greatergreater;
1028 case tok::greaterequal:
1029 RemainingToken = tok::equal;
1030 ReplacementStr =
"> =";
1037 RemainingToken = tok::equalequal;
1038 MergeWithNextToken =
true;
1042 case tok::greatergreaterequal:
1043 RemainingToken = tok::greaterequal;
1062 bool PreventMergeWithNextToken =
1063 (RemainingToken == tok::greater ||
1064 RemainingToken == tok::greatergreater) &&
1065 (Next.isOneOf(tok::greater, tok::greatergreater,
1066 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1067 tok::greatergreaterequal, tok::equalequal)) &&
1068 areTokensAdjacent(Tok, Next);
1071 if (!ObjCGenericList) {
1086 if (PreventMergeWithNextToken)
1089 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1091 (Tok.
is(tok::greatergreater) || Tok.
is(tok::greatergreatergreater)))
1092 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1093 else if (Tok.
is(tok::greaterequal))
1094 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1095 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1106 RAngleLoc = PP.
SplitToken(TokLoc, GreaterLength);
1112 Greater.setLocation(RAngleLoc);
1113 Greater.setKind(tok::greater);
1114 Greater.setLength(GreaterLength);
1117 if (MergeWithNextToken) {
1123 Tok.
setLength(OldLength - GreaterLength);
1128 if (PreventMergeWithNextToken)
1133 if (CachingTokens) {
1135 if (MergeWithNextToken)
1138 if (ConsumeLastToken)
1144 if (ConsumeLastToken) {
1145 PrevTokLocation = RAngleLoc;
1147 PrevTokLocation = TokBeforeGreaterLoc;
1166bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1168 TemplateArgList &TemplateArgs,
1170 TemplateTy Template) {
1171 assert(Tok.
is(tok::less) &&
"Must have already parsed the template-name");
1180 if (!Tok.
isOneOf(tok::greater, tok::greatergreater,
1181 tok::greatergreatergreater, tok::greaterequal,
1182 tok::greatergreaterequal))
1183 Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);
1188 SkipUntil(tok::greater, tok::greatergreater,
1195 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1241bool Parser::AnnotateTemplateIdToken(TemplateTy Template,
TemplateNameKind TNK,
1245 bool AllowTypeAnnotation,
1249 "Parser isn't at the beginning of a template-id");
1250 assert(!(
TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1251 "a type annotation");
1253 "must accompany a concept name");
1261 TemplateArgList TemplateArgs;
1262 bool ArgsInvalid =
false;
1264 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1265 false, LAngleLoc, TemplateArgs, RAngleLoc, Template);
1280 : Actions.ActOnTemplateIdType(
1283 LAngleLoc, TemplateArgsPtr, RAngleLoc);
1285 Tok.
setKind(tok::annot_typename);
1286 setTypeAnnotation(Tok,
Type);
1289 else if (TemplateKWLoc.
isValid())
1296 Tok.
setKind(tok::annot_template_id);
1309 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1310 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1343void Parser::AnnotateTemplateIdTokenAsType(
1346 assert(Tok.
is(tok::annot_template_id) &&
"Requires template-id tokens");
1350 "Only works for type and dependent templates");
1358 : Actions.ActOnTemplateIdType(
1360 TemplateId->Template, TemplateId->Name,
1361 TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1362 TemplateArgsPtr, TemplateId->RAngleLoc,
1363 false, IsClassName, AllowImplicitTypename);
1365 Tok.
setKind(tok::annot_typename);
1366 setTypeAnnotation(Tok,
Type);
1379 return Tok.
isOneOf(tok::comma, tok::greater, tok::greatergreater,
1380 tok::greatergreatergreater);
1385 if (!Tok.
is(tok::identifier) && !Tok.
is(tok::coloncolon) &&
1386 !Tok.
is(tok::annot_cxxscope))
1401 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1407 if (SS.
isSet() && Tok.
is(tok::kw_template)) {
1412 if (Tok.
is(tok::identifier)) {
1430 }
else if (Tok.
is(tok::identifier)) {
1440 bool MemberOfUnknownSpecialization;
1445 false, Template, MemberOfUnknownSpecialization);
1484 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1492 TentativeParsingAction TPA(*
this);
1495 = ParseTemplateTemplateArgument();
1496 if (!TemplateTemplateArgument.
isInvalid()) {
1498 return TemplateTemplateArgument;
1509 ExprArg = ParseBraceInitializer();
1517 ExprArg.
get(), Loc);
1528bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1529 TemplateTy Template,
1534 auto RunSignatureHelp = [&] {
1537 CalledSignatureHelp =
true;
1556 TemplateArgs.push_back(Arg);
1579 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1580 return ParseDeclarationAfterTemplate(
1581 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1584SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1587 TemplateParams->size());
1590 if (ExternLoc.isValid())
1591 R.setBegin(ExternLoc);
1596 ((
Parser *)
P)->ParseLateTemplatedFuncDef(LPT);
1605 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1610 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1616 MultiParseScope Scopes(*
this);
1621 DC = DC->getLexicalParent())
1622 DeclContextsToReenter.push_back(DC);
1625 for (
DeclContext *DC : reverse(DeclContextsToReenter)) {
1626 CurTemplateDepthTracker.addDepth(
1639 assert(!LPT.
Toks.empty() &&
"Empty body!");
1643 LPT.
Toks.push_back(Tok);
1644 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1648 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1649 "Inline method not starting with '{', ':' or 'try'");
1661 if (Tok.
is(tok::kw_try)) {
1662 ParseFunctionTryBlock(LPT.
D, FnScope);
1664 if (Tok.
is(tok::colon))
1665 ParseConstructorInitializer(LPT.
D);
1669 if (Tok.
is(tok::l_brace)) {
1670 assert((!isa<FunctionTemplateDecl>(LPT.
D) ||
1671 cast<FunctionTemplateDecl>(LPT.
D)
1672 ->getTemplateParameters()
1673 ->getDepth() == TemplateParameterDepth - 1) &&
1674 "TemplateParameterDepth should be greater than the depth of "
1675 "current template being instantiated!");
1676 ParseFunctionStatementBody(LPT.
D, FnScope);
1684void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1686 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1688 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1692 if (kind == tok::kw_try) {
1693 while (Tok.
is(tok::kw_catch)) {
1694 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1695 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1705 TentativeParsingAction TPA(*
this);
1707 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1712 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1724void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1725 assert(Tok.
is(tok::less) &&
"not at a potential angle bracket");
1741 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1753 TentativeParsingAction TPA(*
this);
1755 if (isTypeIdUnambiguously() &&
1756 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1767 AngleBracketTracker::Priority
Priority =
1769 : AngleBracketTracker::PotentialTypo) |
1771 : AngleBracketTracker::NoSpaceBeforeLess);
1772 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.
getLocation(),
1776bool Parser::checkPotentialAngleBracketDelimiter(
1777 const AngleBracketTracker::Loc &LAngle,
const Token &OpToken) {
1781 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1782 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1783 AngleBrackets.clear(*
this);
1790 if (OpToken.
is(tok::greater) && Tok.
is(tok::l_paren) &&
1793 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1795 AngleBrackets.clear(*
this);
1801 if (OpToken.
is(tok::greater) ||
1803 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1804 AngleBrackets.clear(*
this);
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
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()
TranslationUnitDecl * getTranslationUnitDecl() const
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.
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
bool isTranslationUnit() const
Captures information about "declaration specifiers".
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)
Represents a dependent template name that cannot be resolved prior to template instantiation.
RAII object that enters a new expression evaluation context.
This represents one expression.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
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.
Represents a function declaration or definition.
RAII object that makes '>' behave either as an operator or as the closing angle bracket for a templat...
One of these records is kept for each identifier that is lexed.
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.
Wrapper for void* pointer.
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.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
AttributeFactory & getAttrFactory()
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
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.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
SourceLocation getEndOfPreviousToken()
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 ...
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
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 the template scopes for a declaration that might be a template.
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
void enterFunctionArgument(SourceLocation Tok, llvm::function_ref< QualType()> ComputeType)
Computing a type for the function argument may require running overloading, so we postpone its comput...
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
bool IsPreviousCachedToken(const Token &Tok) const
Whether Tok is the most recent token (CachedLexPos - 1) in CachedTokens.
void AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
SourceManager & getSourceManager() const
SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length)
Split the first Length characters out of the token starting at TokLoc and return a location pointing ...
void ReplacePreviousCachedToken(ArrayRef< Token > NewToks)
Replace token in CachedLexPos - 1 in CachedTokens by the tokens in NewToks.
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
A (possibly-)qualified type.
Represents a struct/union/class.
@ 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.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
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...
Decl * ActOnConceptDefinition(Scope *S, MultiTemplateParamsArg TemplateParameterLists, const IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr)
NamedDecl * ActOnTemplateTemplateParameter(Scope *S, SourceLocation TmpLoc, TemplateParameterList *Params, bool Typename, SourceLocation EllipsisLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, unsigned Depth, unsigned Position, SourceLocation EqualLoc, ParsedTemplateArgument DefaultArg)
ActOnTemplateTemplateParameter - Called when a C++ template template parameter (e....
bool ActOnTypeConstraint(const CXXScopeSpec &SS, TemplateIdAnnotation *TypeConstraint, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc)
void UnmarkAsLateParsedTemplate(FunctionDecl *FD)
TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool &MemberOfUnknownSpecialization, bool Disambiguation=false)
ParsedTemplateArgument ActOnTemplateTypeArgument(TypeResult ParsedType)
Convert a parsed type into a parsed template argument.
void resetFPOptions(FPOptions FPO)
QualType ProduceTemplateArgumentSignatureHelp(TemplateTy, ArrayRef< ParsedTemplateArgument >, SourceLocation LAngleLoc)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
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.
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)
bool mightBeIntendedToBeTemplateName(ExprResult E, bool &Dependent)
Determine whether it's plausible that E was intended to be a template-name.
TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool AllowInjectedClassName=false)
Form a template name from a name that is syntactically required to name a template,...
unsigned ActOnReenterTemplateScope(Decl *Template, llvm::function_ref< Scope *()> EnterScope)
void diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, SourceLocation Less, SourceLocation Greater)
Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
ExprResult ActOnRequiresClause(ExprResult ConstraintExpr)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
NamedDecl * ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, SourceLocation EqualLoc, Expr *DefaultArg)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, 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...
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.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
void setAnnotationEndLoc(SourceLocation L)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
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
tok::TokenKind getKind() const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setAnnotationValue(void *val)
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
The base class of the type hierarchy.
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.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
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.
@ IK_Identifier
An identifier.
@ Result
The result type of a method or function.
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ 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.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
const FunctionProtoType * T
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Contains a late templated function.
FPOptions FPO
Floating-point options in the point of definition.
Decl * D
The template function declaration to be late parsed.
Information about a template-id annotation token.
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.
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.