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);
349 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
350 Expr *ConstraintExpr = ConstraintExprResult.
get();
368bool Parser::ParseTemplateParameters(
369 MultiParseScope &TemplateScopes,
unsigned Depth,
381 if (!Tok.
is(tok::greater) && !Tok.
is(tok::greatergreater)) {
383 Failed = ParseTemplateParameterList(Depth, TemplateParams);
386 if (Tok.
is(tok::greatergreater)) {
411Parser::ParseTemplateParameterList(
const unsigned Depth,
416 = ParseTemplateParameter(Depth, TemplateParams.size())) {
417 TemplateParams.push_back(TmpParam);
421 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
426 if (Tok.
is(tok::comma)) {
428 }
else if (Tok.
isOneOf(tok::greater, tok::greatergreater)) {
436 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
446Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
447 if (Tok.
is(tok::kw_class)) {
454 case tok::greatergreater:
456 return TPResult::True;
458 case tok::identifier:
464 return TPResult::False;
467 switch (GetLookAheadToken(2).
getKind()) {
471 case tok::greatergreater:
472 return TPResult::True;
475 return TPResult::False;
479 if (TryAnnotateTypeConstraint())
480 return TPResult::Error;
482 if (isTypeConstraintAnnotation() &&
486 !GetLookAheadToken(Tok.
is(tok::annot_cxxscope) ? 2 : 1)
487 .
isOneOf(tok::kw_auto, tok::kw_decltype))
488 return TPResult::True;
492 if (Tok.
isNot(tok::kw_typename) && Tok.
isNot(tok::kw_typedef))
493 return TPResult::False;
504 if (Next.getKind() == tok::identifier)
505 Next = GetLookAheadToken(2);
507 switch (Next.getKind()) {
511 case tok::greatergreater:
513 return TPResult::True;
515 case tok::kw_typename:
516 case tok::kw_typedef:
520 return TPResult::True;
523 return TPResult::False;
547NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
549 switch (isStartOfTemplateTypeParameter()) {
553 if (Tok.
is(tok::kw_typedef)) {
565 return ParseTypeParameter(Depth, Position);
566 case TPResult::False:
569 case TPResult::Error: {
577 DS.SetTypeSpecError();
581 D.setInvalidType(
true);
586 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
591 case TPResult::Ambiguous:
592 llvm_unreachable(
"template param classification can't be ambiguous");
595 if (Tok.
is(tok::kw_template))
596 return ParseTemplateTemplateParameter(Depth, Position);
601 return ParseNonTypeTemplateParameter(Depth, Position);
606bool Parser::isTypeConstraintAnnotation() {
608 if (
T.isNot(tok::annot_template_id))
610 const auto *ExistingAnnot =
623bool Parser::TryAnnotateTypeConstraint() {
627 bool WasScopeAnnotation = Tok.
is(tok::annot_cxxscope);
628 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
643 if (Tok.
is(tok::identifier)) {
649 bool MemberOfUnknownSpecialization =
false;
656 MemberOfUnknownSpecialization,
658 if (MemberOfUnknownSpecialization || !PossibleConcept ||
661 AnnotateScopeToken(SS, !WasScopeAnnotation);
668 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
677 AnnotateScopeToken(SS, !WasScopeAnnotation);
690NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
691 assert((Tok.
isOneOf(tok::kw_class, tok::kw_typename) ||
692 isTypeConstraintAnnotation()) &&
693 "A type-parameter starts with 'class', 'typename' or a "
698 bool TypenameKeyword =
false;
700 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
703 if (Tok.
is(tok::annot_template_id)) {
708 "stray non-concept template-id annotation");
709 KeyLoc = ConsumeAnnotationToken();
711 assert(TypeConstraintSS.
isEmpty() &&
712 "expected type constraint after scope specifier");
715 TypenameKeyword = Tok.
is(tok::kw_typename);
724 ? diag::warn_cxx98_compat_variadic_templates
725 : diag::ext_variadic_templates);
731 if (Tok.
is(tok::identifier)) {
734 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
735 tok::greatergreater)) {
744 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
746 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
753 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
758 DontDestructTemplateIds.emplace(*
this,
true);
763 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
764 ++CurTemplateDepthTracker;
771 TypenameKeyword, EllipsisLoc,
772 KeyLoc, ParamName, NameLoc,
773 Depth, Position, EqualLoc,
779 cast<TemplateTypeParmDecl>(NewDecl),
798NamedDecl *Parser::ParseTemplateTemplateParameter(
unsigned Depth,
800 assert(Tok.
is(tok::kw_template) &&
"Expected 'template' keyword");
806 ExprResult OptionalRequiresClauseConstraintER;
808 MultiParseScope TemplateParmScope(*
this);
809 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
810 LAngleLoc, RAngleLoc)) {
814 OptionalRequiresClauseConstraintER =
817 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
818 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
830 bool TypenameKeyword =
false;
832 bool Replace = Tok.
isOneOf(tok::kw_typename, tok::kw_struct);
834 if (Tok.
is(tok::kw_typename)) {
835 TypenameKeyword =
true;
838 ? diag::warn_cxx14_compat_template_template_param_typename
839 : diag::ext_template_template_param_typename)
843 }
else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
844 tok::greatergreater, tok::ellipsis)) {
849 :
FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
863 ? diag::warn_cxx98_compat_variadic_templates
864 : diag::ext_variadic_templates);
869 if (Tok.
is(tok::identifier)) {
872 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
873 tok::greatergreater)) {
882 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
884 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
888 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
896 DefaultArg = ParseTemplateTemplateArgument();
899 diag::err_default_template_template_parameter_not_template);
900 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
906 getCurScope(), TemplateLoc, ParamList, TypenameKeyword, EllipsisLoc,
907 ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
917Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
922 ParsedTemplateInfo TemplateInfo;
923 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
924 DeclSpecContext::DSC_template_param);
929 ParseDeclarator(ParamDecl);
938 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
946 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
961 TemplateParameterDepthRAII CurTemplateDepthTracker(
962 TemplateParameterDepth);
963 ++CurTemplateDepthTracker;
974 Depth, Position, EqualLoc,
980 bool AlreadyHasEllipsis,
981 bool IdentifierHasName) {
983 if (!AlreadyHasEllipsis)
985 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
987 << !IdentifierHasName;
990void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
993 bool AlreadyHasEllipsis =
D.getEllipsisLoc().isValid();
994 if (!AlreadyHasEllipsis)
995 D.setEllipsisLoc(EllipsisLoc);
996 DiagnoseMisplacedEllipsis(EllipsisLoc,
D.getIdentifierLoc(),
997 AlreadyHasEllipsis,
D.hasName());
1015bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
1017 bool ConsumeLastToken,
1018 bool ObjCGenericList) {
1021 const char *ReplacementStr =
"> >";
1022 bool MergeWithNextToken =
false;
1027 Diag(LAngleLoc, diag::note_matching) << tok::less;
1034 if (ConsumeLastToken)
1038 case tok::greatergreater:
1039 RemainingToken = tok::greater;
1042 case tok::greatergreatergreater:
1043 RemainingToken = tok::greatergreater;
1046 case tok::greaterequal:
1047 RemainingToken = tok::equal;
1048 ReplacementStr =
"> =";
1055 RemainingToken = tok::equalequal;
1056 MergeWithNextToken =
true;
1060 case tok::greatergreaterequal:
1061 RemainingToken = tok::greaterequal;
1080 bool PreventMergeWithNextToken =
1081 (RemainingToken == tok::greater ||
1082 RemainingToken == tok::greatergreater) &&
1083 (Next.isOneOf(tok::greater, tok::greatergreater,
1084 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1085 tok::greatergreaterequal, tok::equalequal)) &&
1086 areTokensAdjacent(Tok, Next);
1089 if (!ObjCGenericList) {
1104 if (PreventMergeWithNextToken)
1107 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1109 (Tok.
is(tok::greatergreater) || Tok.
is(tok::greatergreatergreater)))
1110 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1111 else if (Tok.
is(tok::greaterequal))
1112 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1113 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1124 RAngleLoc = PP.
SplitToken(TokLoc, GreaterLength);
1130 Greater.setLocation(RAngleLoc);
1131 Greater.setKind(tok::greater);
1132 Greater.setLength(GreaterLength);
1135 if (MergeWithNextToken) {
1141 Tok.
setLength(OldLength - GreaterLength);
1146 if (PreventMergeWithNextToken)
1151 if (CachingTokens) {
1153 if (MergeWithNextToken)
1156 if (ConsumeLastToken)
1162 if (ConsumeLastToken) {
1163 PrevTokLocation = RAngleLoc;
1165 PrevTokLocation = TokBeforeGreaterLoc;
1184bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1186 TemplateArgList &TemplateArgs,
1188 TemplateTy Template) {
1189 assert(Tok.
is(tok::less) &&
"Must have already parsed the template-name");
1198 if (!Tok.
isOneOf(tok::greater, tok::greatergreater,
1199 tok::greatergreatergreater, tok::greaterequal,
1200 tok::greatergreaterequal))
1201 Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);
1206 SkipUntil(tok::greater, tok::greatergreater,
1213 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1259bool Parser::AnnotateTemplateIdToken(TemplateTy Template,
TemplateNameKind TNK,
1263 bool AllowTypeAnnotation,
1267 "Parser isn't at the beginning of a template-id");
1268 assert(!(
TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1269 "a type annotation");
1271 "must accompany a concept name");
1279 TemplateArgList TemplateArgs;
1280 bool ArgsInvalid =
false;
1282 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1283 false, LAngleLoc, TemplateArgs, RAngleLoc, Template);
1298 : Actions.ActOnTemplateIdType(
1301 LAngleLoc, TemplateArgsPtr, RAngleLoc);
1303 Tok.
setKind(tok::annot_typename);
1304 setTypeAnnotation(Tok,
Type);
1307 else if (TemplateKWLoc.
isValid())
1314 Tok.
setKind(tok::annot_template_id);
1327 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1328 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1361void Parser::AnnotateTemplateIdTokenAsType(
1364 assert(Tok.
is(tok::annot_template_id) &&
"Requires template-id tokens");
1368 "Only works for type and dependent templates");
1376 : Actions.ActOnTemplateIdType(
1378 TemplateId->Template, TemplateId->Name,
1379 TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1380 TemplateArgsPtr, TemplateId->RAngleLoc,
1381 false, IsClassName, AllowImplicitTypename);
1383 Tok.
setKind(tok::annot_typename);
1384 setTypeAnnotation(Tok,
Type);
1397 return Tok.
isOneOf(tok::comma, tok::greater, tok::greatergreater,
1398 tok::greatergreatergreater);
1403 if (!Tok.
is(tok::identifier) && !Tok.
is(tok::coloncolon) &&
1404 !Tok.
is(tok::annot_cxxscope))
1419 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1425 if (SS.
isSet() && Tok.
is(tok::kw_template)) {
1430 if (Tok.
is(tok::identifier)) {
1448 }
else if (Tok.
is(tok::identifier)) {
1458 bool MemberOfUnknownSpecialization;
1463 false, Template, MemberOfUnknownSpecialization);
1502 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1510 TentativeParsingAction TPA(*
this);
1513 = ParseTemplateTemplateArgument();
1514 if (!TemplateTemplateArgument.
isInvalid()) {
1516 return TemplateTemplateArgument;
1527 ExprArg = ParseBraceInitializer();
1546bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1547 TemplateTy Template,
1552 auto RunSignatureHelp = [&] {
1555 CalledSignatureHelp =
true;
1557 Template, TemplateArgs, OpenLoc);
1574 TemplateArgs.push_back(Arg);
1597 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1598 return ParseDeclarationAfterTemplate(
1599 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1602SourceRange Parser::ParsedTemplateInfo::getSourceRange()
const {
1605 TemplateParams->size());
1608 if (ExternLoc.isValid())
1609 R.setBegin(ExternLoc);
1614 ((
Parser *)
P)->ParseLateTemplatedFuncDef(LPT);
1623 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1628 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1634 MultiParseScope Scopes(*
this);
1639 DC = DC->getLexicalParent())
1640 DeclContextsToReenter.push_back(DC);
1643 for (
DeclContext *DC : reverse(DeclContextsToReenter)) {
1644 CurTemplateDepthTracker.addDepth(
1657 assert(!LPT.
Toks.empty() &&
"Empty body!");
1661 LPT.
Toks.push_back(Tok);
1662 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1666 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1667 "Inline method not starting with '{', ':' or 'try'");
1679 if (Tok.
is(tok::kw_try)) {
1680 ParseFunctionTryBlock(LPT.
D, FnScope);
1682 if (Tok.
is(tok::colon))
1683 ParseConstructorInitializer(LPT.
D);
1687 if (Tok.
is(tok::l_brace)) {
1688 assert((!isa<FunctionTemplateDecl>(LPT.
D) ||
1689 cast<FunctionTemplateDecl>(LPT.
D)
1690 ->getTemplateParameters()
1691 ->getDepth() == TemplateParameterDepth - 1) &&
1692 "TemplateParameterDepth should be greater than the depth of "
1693 "current template being instantiated!");
1694 ParseFunctionStatementBody(LPT.
D, FnScope);
1702void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1704 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1706 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1710 if (kind == tok::kw_try) {
1711 while (Tok.
is(tok::kw_catch)) {
1712 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1713 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1723 TentativeParsingAction TPA(*
this);
1725 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1730 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1742void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1743 assert(Tok.
is(tok::less) &&
"not at a potential angle bracket");
1759 ParseGreaterThanInTemplateList(
Less,
Greater,
true,
false);
1771 TentativeParsingAction TPA(*
this);
1773 if (isTypeIdUnambiguously() &&
1774 diagnoseUnknownTemplateId(PotentialTemplateName,
Less)) {
1785 AngleBracketTracker::Priority
Priority =
1787 : AngleBracketTracker::PotentialTypo) |
1789 : AngleBracketTracker::NoSpaceBeforeLess);
1790 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.
getLocation(),
1794bool Parser::checkPotentialAngleBracketDelimiter(
1795 const AngleBracketTracker::Loc &LAngle,
const Token &OpToken) {
1799 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1800 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1801 AngleBrackets.clear(*
this);
1808 if (OpToken.
is(tok::greater) && Tok.
is(tok::l_paren) &&
1811 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1813 AngleBrackets.clear(*
this);
1819 if (OpToken.
is(tok::greater) ||
1821 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1822 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.
ExprResult ActOnConstantExpression(ExprResult Res)
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.