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)) {
178 return ParseDeclarationAfterTemplate(
179 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
196 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
197 "Template information required");
199 if (Tok.
is(tok::kw_static_assert)) {
202 << TemplateInfo.getSourceRange();
205 ParseStaticAssertDeclaration(DeclEnd));
210 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
220 while (MaybeParseCXX11Attributes(DeclAttrs) ||
221 MaybeParseGNUAttributes(DeclSpecAttrs))
224 if (Tok.
is(tok::kw_using))
225 return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
231 DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
232 DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
233 DS.takeAttributesFrom(DeclSpecAttrs);
235 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
236 getDeclSpecContextFromDeclaratorContext(Context));
238 if (Tok.
is(tok::semi)) {
239 ProhibitAttributes(DeclAttrs);
244 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
246 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation,
249 assert(!AnonRecord &&
250 "Anonymous unions/structs should not be valid with template");
255 if (DS.hasTagDefinition())
259 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
260 ProhibitAttributes(DeclAttrs);
262 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd);
272Parser::ParseConceptDefinition(
const ParsedTemplateInfo &TemplateInfo,
274 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
275 "Template information required");
276 assert(Tok.
is(tok::kw_concept) &&
277 "ParseConceptDefinition must be called when at a 'concept' keyword");
286 DiagnoseAndSkipCXX11Attributes();
289 if (ParseOptionalCXXScopeSpecifier(
293 false,
nullptr,
true) ||
301 diag::err_concept_definition_not_identifier);
315 Diag(
Result.getBeginLoc(), diag::err_concept_definition_not_identifier);
329 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
345 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
346 Expr *ConstraintExpr = ConstraintExprResult.
get();
364bool Parser::ParseTemplateParameters(
365 MultiParseScope &TemplateScopes,
unsigned Depth,
377 if (!Tok.
is(tok::greater) && !Tok.
is(tok::greatergreater)) {
379 Failed = ParseTemplateParameterList(Depth, TemplateParams);
382 if (Tok.
is(tok::greatergreater)) {
407Parser::ParseTemplateParameterList(
const unsigned Depth,
412 = ParseTemplateParameter(Depth, TemplateParams.size())) {
413 TemplateParams.push_back(TmpParam);
417 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
422 if (Tok.
is(tok::comma)) {
424 }
else if (Tok.
isOneOf(tok::greater, tok::greatergreater)) {
432 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
442Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
443 if (Tok.
is(tok::kw_class)) {
450 case tok::greatergreater:
452 return TPResult::True;
454 case tok::identifier:
460 return TPResult::False;
463 switch (GetLookAheadToken(2).
getKind()) {
467 case tok::greatergreater:
468 return TPResult::True;
471 return TPResult::False;
475 if (TryAnnotateTypeConstraint())
476 return TPResult::Error;
478 if (isTypeConstraintAnnotation() &&
482 !GetLookAheadToken(Tok.
is(tok::annot_cxxscope) ? 2 : 1)
483 .
isOneOf(tok::kw_auto, tok::kw_decltype))
484 return TPResult::True;
488 if (Tok.
isNot(tok::kw_typename) && Tok.
isNot(tok::kw_typedef))
489 return TPResult::False;
500 if (Next.getKind() == tok::identifier)
501 Next = GetLookAheadToken(2);
503 switch (Next.getKind()) {
507 case tok::greatergreater:
509 return TPResult::True;
511 case tok::kw_typename:
512 case tok::kw_typedef:
516 return TPResult::True;
519 return TPResult::False;
543NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
545 switch (isStartOfTemplateTypeParameter()) {
549 if (Tok.
is(tok::kw_typedef)) {
561 return ParseTypeParameter(Depth, Position);
562 case TPResult::False:
565 case TPResult::Error: {
573 DS.SetTypeSpecError();
577 D.setInvalidType(
true);
582 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
587 case TPResult::Ambiguous:
588 llvm_unreachable(
"template param classification can't be ambiguous");
591 if (Tok.
is(tok::kw_template))
592 return ParseTemplateTemplateParameter(Depth, Position);
597 return ParseNonTypeTemplateParameter(Depth, Position);
602bool Parser::isTypeConstraintAnnotation() {
604 if (
T.isNot(tok::annot_template_id))
606 const auto *ExistingAnnot =
619bool Parser::TryAnnotateTypeConstraint() {
623 bool WasScopeAnnotation = Tok.
is(tok::annot_cxxscope);
624 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
639 if (Tok.
is(tok::identifier)) {
645 bool MemberOfUnknownSpecialization =
false;
652 MemberOfUnknownSpecialization,
654 if (MemberOfUnknownSpecialization || !PossibleConcept ||
657 AnnotateScopeToken(SS, !WasScopeAnnotation);
664 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
673 AnnotateScopeToken(SS, !WasScopeAnnotation);
686NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
687 assert((Tok.
isOneOf(tok::kw_class, tok::kw_typename) ||
688 isTypeConstraintAnnotation()) &&
689 "A type-parameter starts with 'class', 'typename' or a "
694 bool TypenameKeyword =
false;
696 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
699 if (Tok.
is(tok::annot_template_id)) {
704 "stray non-concept template-id annotation");
705 KeyLoc = ConsumeAnnotationToken();
707 assert(TypeConstraintSS.
isEmpty() &&
708 "expected type constraint after scope specifier");
711 TypenameKeyword = Tok.
is(tok::kw_typename);
720 ? diag::warn_cxx98_compat_variadic_templates
721 : diag::ext_variadic_templates);
727 if (Tok.
is(tok::identifier)) {
730 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
731 tok::greatergreater)) {
740 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
742 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
749 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
754 DontDestructTemplateIds.emplace(*
this,
true);
759 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
760 ++CurTemplateDepthTracker;
767 TypenameKeyword, EllipsisLoc,
768 KeyLoc, ParamName, NameLoc,
769 Depth, Position, EqualLoc,
775 cast<TemplateTypeParmDecl>(NewDecl),
794NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
796 assert(Tok.
is(tok::kw_template) &&
"Expected 'template' keyword");
802 ExprResult OptionalRequiresClauseConstraintER;
804 MultiParseScope TemplateParmScope(*
this);
805 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
806 LAngleLoc, RAngleLoc)) {
810 OptionalRequiresClauseConstraintER =
813 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
814 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
826 bool TypenameKeyword =
false;
828 bool Replace = Tok.
isOneOf(tok::kw_typename, tok::kw_struct);
830 if (Tok.
is(tok::kw_typename)) {
831 TypenameKeyword =
true;
834 ? diag::warn_cxx14_compat_template_template_param_typename
835 : diag::ext_template_template_param_typename)
839 }
else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
840 tok::greatergreater, tok::ellipsis)) {
845 :
FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
859 ? diag::warn_cxx98_compat_variadic_templates
860 : diag::ext_variadic_templates);
865 if (Tok.
is(tok::identifier)) {
868 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
869 tok::greatergreater)) {
878 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
880 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
884 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
892 DefaultArg = ParseTemplateTemplateArgument();
895 diag::err_default_template_template_parameter_not_template);
896 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
902 getCurScope(), TemplateLoc, ParamList, TypenameKeyword, EllipsisLoc,
903 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
913Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
918 ParsedTemplateInfo TemplateInfo;
919 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
920 DeclSpecContext::DSC_template_param);
925 ParseDeclarator(ParamDecl);
934 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
942 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
957 TemplateParameterDepthRAII CurTemplateDepthTracker(
958 TemplateParameterDepth);
959 ++CurTemplateDepthTracker;
970 Depth, Position, EqualLoc,
976 bool AlreadyHasEllipsis,
977 bool IdentifierHasName) {
979 if (!AlreadyHasEllipsis)
981 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
983 << !IdentifierHasName;
986void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
989 bool AlreadyHasEllipsis =
D.getEllipsisLoc().isValid();
990 if (!AlreadyHasEllipsis)
991 D.setEllipsisLoc(EllipsisLoc);
992 DiagnoseMisplacedEllipsis(EllipsisLoc,
D.getIdentifierLoc(),
993 AlreadyHasEllipsis,
D.hasName());
1011bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
1013 bool ConsumeLastToken,
1014 bool ObjCGenericList) {
1017 const char *ReplacementStr =
"> >";
1018 bool MergeWithNextToken =
false;
1023 Diag(LAngleLoc, diag::note_matching) << tok::less;
1030 if (ConsumeLastToken)
1034 case tok::greatergreater:
1035 RemainingToken = tok::greater;
1038 case tok::greatergreatergreater:
1039 RemainingToken = tok::greatergreater;
1042 case tok::greaterequal:
1043 RemainingToken = tok::equal;
1044 ReplacementStr =
"> =";
1051 RemainingToken = tok::equalequal;
1052 MergeWithNextToken =
true;
1056 case tok::greatergreaterequal:
1057 RemainingToken = tok::greaterequal;
1076 bool PreventMergeWithNextToken =
1077 (RemainingToken == tok::greater ||
1078 RemainingToken == tok::greatergreater) &&
1079 (Next.isOneOf(tok::greater, tok::greatergreater,
1080 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1081 tok::greatergreaterequal, tok::equalequal)) &&
1082 areTokensAdjacent(Tok, Next);
1085 if (!ObjCGenericList) {
1100 if (PreventMergeWithNextToken)
1103 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1105 (Tok.
is(tok::greatergreater) || Tok.
is(tok::greatergreatergreater)))
1106 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1107 else if (Tok.
is(tok::greaterequal))
1108 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1109 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1120 RAngleLoc = PP.
SplitToken(TokLoc, GreaterLength);
1126 Greater.setLocation(RAngleLoc);
1127 Greater.setKind(tok::greater);
1128 Greater.setLength(GreaterLength);
1131 if (MergeWithNextToken) {
1137 Tok.
setLength(OldLength - GreaterLength);
1142 if (PreventMergeWithNextToken)
1147 if (CachingTokens) {
1149 if (MergeWithNextToken)
1152 if (ConsumeLastToken)
1158 if (ConsumeLastToken) {
1159 PrevTokLocation = RAngleLoc;
1161 PrevTokLocation = TokBeforeGreaterLoc;
1180bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1182 TemplateArgList &TemplateArgs,
1184 TemplateTy Template) {
1185 assert(Tok.
is(tok::less) &&
"Must have already parsed the template-name");
1194 if (!Tok.
isOneOf(tok::greater, tok::greatergreater,
1195 tok::greatergreatergreater, tok::greaterequal,
1196 tok::greatergreaterequal))
1197 Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);
1202 SkipUntil(tok::greater, tok::greatergreater,
1209 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1255bool Parser::AnnotateTemplateIdToken(TemplateTy Template,
TemplateNameKind TNK,
1259 bool AllowTypeAnnotation,
1263 "Parser isn't at the beginning of a template-id");
1264 assert(!(
TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1265 "a type annotation");
1267 "must accompany a concept name");
1275 TemplateArgList TemplateArgs;
1276 bool ArgsInvalid =
false;
1278 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1279 false, LAngleLoc, TemplateArgs, RAngleLoc, Template);
1294 : Actions.ActOnTemplateIdType(
1297 LAngleLoc, TemplateArgsPtr, RAngleLoc);
1299 Tok.
setKind(tok::annot_typename);
1300 setTypeAnnotation(Tok,
Type);
1303 else if (TemplateKWLoc.
isValid())
1310 Tok.
setKind(tok::annot_template_id);
1323 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1324 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1357void Parser::AnnotateTemplateIdTokenAsType(
1360 assert(Tok.
is(tok::annot_template_id) &&
"Requires template-id tokens");
1364 "Only works for type and dependent templates");
1372 : Actions.ActOnTemplateIdType(
1374 TemplateId->Template, TemplateId->Name,
1375 TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1376 TemplateArgsPtr, TemplateId->RAngleLoc,
1377 false, IsClassName, AllowImplicitTypename);
1379 Tok.
setKind(tok::annot_typename);
1380 setTypeAnnotation(Tok,
Type);
1393 return Tok.
isOneOf(tok::comma, tok::greater, tok::greatergreater,
1394 tok::greatergreatergreater);
1399 if (!Tok.
is(tok::identifier) && !Tok.
is(tok::coloncolon) &&
1400 !Tok.
is(tok::annot_cxxscope))
1415 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1421 if (SS.
isSet() && Tok.
is(tok::kw_template)) {
1426 if (Tok.
is(tok::identifier)) {
1444 }
else if (Tok.
is(tok::identifier)) {
1454 bool MemberOfUnknownSpecialization;
1459 false, Template, MemberOfUnknownSpecialization);
1498 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1506 TentativeParsingAction TPA(*
this);
1509 = ParseTemplateTemplateArgument();
1510 if (!TemplateTemplateArgument.
isInvalid()) {
1512 return TemplateTemplateArgument;
1523 ExprArg = ParseBraceInitializer();
1542bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1543 TemplateTy Template,
1548 auto RunSignatureHelp = [&] {
1551 CalledSignatureHelp =
true;
1553 Template, TemplateArgs, OpenLoc);
1570 TemplateArgs.push_back(Arg);
1593 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1594 return ParseDeclarationAfterTemplate(
1595 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1598SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1601 TemplateParams->size());
1604 if (ExternLoc.isValid())
1605 R.setBegin(ExternLoc);
1610 ((
Parser *)
P)->ParseLateTemplatedFuncDef(LPT);
1619 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1624 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1630 MultiParseScope Scopes(*
this);
1635 DC = DC->getLexicalParent())
1636 DeclContextsToReenter.push_back(DC);
1639 for (
DeclContext *DC : reverse(DeclContextsToReenter)) {
1640 CurTemplateDepthTracker.addDepth(
1653 assert(!LPT.
Toks.empty() &&
"Empty body!");
1657 LPT.
Toks.push_back(Tok);
1658 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1662 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1663 "Inline method not starting with '{', ':' or 'try'");
1675 if (Tok.
is(tok::kw_try)) {
1676 ParseFunctionTryBlock(LPT.
D, FnScope);
1678 if (Tok.
is(tok::colon))
1679 ParseConstructorInitializer(LPT.
D);
1683 if (Tok.
is(tok::l_brace)) {
1684 assert((!isa<FunctionTemplateDecl>(LPT.
D) ||
1685 cast<FunctionTemplateDecl>(LPT.
D)
1686 ->getTemplateParameters()
1687 ->getDepth() == TemplateParameterDepth - 1) &&
1688 "TemplateParameterDepth should be greater than the depth of "
1689 "current template being instantiated!");
1690 ParseFunctionStatementBody(LPT.
D, FnScope);
1698void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1700 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1702 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1706 if (kind == tok::kw_try) {
1707 while (Tok.
is(tok::kw_catch)) {
1708 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1709 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1719 TentativeParsingAction TPA(*
this);
1721 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1726 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1738void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1739 assert(Tok.
is(tok::less) &&
"not at a potential angle bracket");
1755 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1767 TentativeParsingAction TPA(*
this);
1769 if (isTypeIdUnambiguously() &&
1770 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1781 AngleBracketTracker::Priority
Priority =
1783 : AngleBracketTracker::PotentialTypo) |
1785 : AngleBracketTracker::NoSpaceBeforeLess);
1786 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.
getLocation(),
1790bool Parser::checkPotentialAngleBracketDelimiter(
1791 const AngleBracketTracker::Loc &LAngle,
const Token &OpToken) {
1795 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1796 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1797 AngleBrackets.clear(*
this);
1804 if (OpToken.
is(tok::greater) && Tok.
is(tok::l_paren) &&
1807 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1809 AngleBrackets.clear(*
this);
1815 if (OpToken.
is(tok::greater) ||
1817 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1818 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.
Declaration of a C++20 concept.
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.
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.
QualType ProduceTemplateArgumentSignatureHelp(TemplateTy, ArrayRef< ParsedTemplateArgument >, SourceLocation LAngleLoc)
ConceptDecl * ActOnStartConceptDefinition(Scope *S, MultiTemplateParamsArg TemplateParameterLists, const IdentifierInfo *Name, SourceLocation NameLoc)
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...
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)
ConceptDecl * ActOnFinishConceptDefinition(Scope *S, ConceptDecl *C, Expr *ConstraintExpr, const ParsedAttributesView &Attrs)
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)
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.
SemaCodeCompletion & CodeCompletion()
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.