24 #include "llvm/Support/TimeProfiler.h"
25 using namespace clang;
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);
272 Parser::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);
324 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
340 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
341 Expr *ConstraintExpr = ConstraintExprResult.
get();
343 *TemplateInfo.TemplateParams,
Id, IdLoc,
344 ConstraintExpr, Attrs);
356 bool Parser::ParseTemplateParameters(
357 MultiParseScope &TemplateScopes,
unsigned Depth,
369 if (!Tok.
is(tok::greater) && !Tok.
is(tok::greatergreater)) {
371 Failed = ParseTemplateParameterList(
Depth, TemplateParams);
374 if (Tok.
is(tok::greatergreater)) {
399 Parser::ParseTemplateParameterList(
const unsigned Depth,
404 = ParseTemplateParameter(
Depth, TemplateParams.size())) {
405 TemplateParams.push_back(TmpParam);
409 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
414 if (Tok.
is(tok::comma)) {
416 }
else if (Tok.
isOneOf(tok::greater, tok::greatergreater)) {
424 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
434 Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
435 if (Tok.
is(tok::kw_class)) {
442 case tok::greatergreater:
444 return TPResult::True;
446 case tok::identifier:
452 return TPResult::False;
455 switch (GetLookAheadToken(2).
getKind()) {
459 case tok::greatergreater:
460 return TPResult::True;
463 return TPResult::False;
467 if (TryAnnotateTypeConstraint())
468 return TPResult::Error;
470 if (isTypeConstraintAnnotation() &&
474 !GetLookAheadToken(Tok.
is(tok::annot_cxxscope) ? 2 : 1)
475 .
isOneOf(tok::kw_auto, tok::kw_decltype))
476 return TPResult::True;
480 if (Tok.
isNot(tok::kw_typename) && Tok.
isNot(tok::kw_typedef))
481 return TPResult::False;
492 if (Next.getKind() == tok::identifier)
493 Next = GetLookAheadToken(2);
495 switch (Next.getKind()) {
499 case tok::greatergreater:
501 return TPResult::True;
503 case tok::kw_typename:
504 case tok::kw_typedef:
508 return TPResult::True;
511 return TPResult::False;
535 NamedDecl *Parser::ParseTemplateParameter(
unsigned Depth,
unsigned Position) {
537 switch (isStartOfTemplateTypeParameter()) {
541 if (Tok.
is(tok::kw_typedef)) {
553 return ParseTypeParameter(
Depth, Position);
554 case TPResult::False:
557 case TPResult::Error: {
565 DS.SetTypeSpecError();
569 D.setInvalidType(
true);
574 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
579 case TPResult::Ambiguous:
580 llvm_unreachable(
"template param classification can't be ambiguous");
583 if (Tok.
is(tok::kw_template))
584 return ParseTemplateTemplateParameter(
Depth, Position);
589 return ParseNonTypeTemplateParameter(
Depth, Position);
594 bool Parser::isTypeConstraintAnnotation() {
596 if (
T.isNot(tok::annot_template_id))
598 const auto *ExistingAnnot =
611 bool Parser::TryAnnotateTypeConstraint() {
615 bool WasScopeAnnotation = Tok.
is(tok::annot_cxxscope);
616 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
631 if (Tok.
is(tok::identifier)) {
637 bool MemberOfUnknownSpecialization =
false;
644 MemberOfUnknownSpecialization,
646 if (MemberOfUnknownSpecialization || !PossibleConcept ||
649 AnnotateScopeToken(SS, !WasScopeAnnotation);
656 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
665 AnnotateScopeToken(SS, !WasScopeAnnotation);
678 NamedDecl *Parser::ParseTypeParameter(
unsigned Depth,
unsigned Position) {
679 assert((Tok.
isOneOf(tok::kw_class, tok::kw_typename) ||
680 isTypeConstraintAnnotation()) &&
681 "A type-parameter starts with 'class', 'typename' or a "
686 bool TypenameKeyword =
false;
688 ParseOptionalCXXScopeSpecifier(TypeConstraintSS,
nullptr,
691 if (Tok.
is(tok::annot_template_id)) {
696 "stray non-concept template-id annotation");
697 KeyLoc = ConsumeAnnotationToken();
699 assert(TypeConstraintSS.
isEmpty() &&
700 "expected type constraint after scope specifier");
703 TypenameKeyword = Tok.
is(tok::kw_typename);
712 ? diag::warn_cxx98_compat_variadic_templates
713 : diag::ext_variadic_templates);
719 if (Tok.
is(tok::identifier)) {
722 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
723 tok::greatergreater)) {
732 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
734 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
741 std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;
746 DontDestructTemplateIds.emplace(*
this,
true);
751 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
752 ++CurTemplateDepthTracker;
759 TypenameKeyword, EllipsisLoc,
760 KeyLoc, ParamName, NameLoc,
761 Depth, Position, EqualLoc,
767 cast<TemplateTypeParmDecl>(NewDecl),
788 assert(Tok.
is(tok::kw_template) &&
"Expected 'template' keyword");
794 ExprResult OptionalRequiresClauseConstraintER;
796 MultiParseScope TemplateParmScope(*
this);
797 if (ParseTemplateParameters(TemplateParmScope,
Depth + 1, TemplateParams,
798 LAngleLoc, RAngleLoc)) {
802 OptionalRequiresClauseConstraintER =
805 if (!OptionalRequiresClauseConstraintER.
isUsable()) {
806 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
818 bool TypenameKeyword =
false;
820 bool Replace = Tok.
isOneOf(tok::kw_typename, tok::kw_struct);
822 if (Tok.
is(tok::kw_typename)) {
823 TypenameKeyword =
true;
826 ? diag::warn_cxx14_compat_template_template_param_typename
827 : diag::ext_template_template_param_typename)
831 }
else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
832 tok::greatergreater, tok::ellipsis)) {
837 :
FixItHint::CreateInsertion(Tok.getLocation(),
"class "));
851 ? diag::warn_cxx98_compat_variadic_templates
852 : diag::ext_variadic_templates);
857 if (Tok.
is(tok::identifier)) {
860 }
else if (Tok.
isOneOf(tok::equal, tok::comma, tok::greater,
861 tok::greatergreater)) {
870 bool AlreadyHasEllipsis = EllipsisLoc.
isValid();
872 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis,
true);
876 RAngleLoc, OptionalRequiresClauseConstraintER.
get());
884 DefaultArg = ParseTemplateTemplateArgument();
887 diag::err_default_template_template_parameter_not_template);
888 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
894 getCurScope(), TemplateLoc, ParamList, TypenameKeyword, EllipsisLoc,
895 ParamName, NameLoc,
Depth, Position, EqualLoc, DefaultArg);
905 Parser::ParseNonTypeTemplateParameter(
unsigned Depth,
unsigned Position) {
910 ParsedTemplateInfo TemplateInfo;
911 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
912 DeclSpecContext::DSC_template_param);
917 ParseDeclarator(ParamDecl);
926 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
934 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
949 TemplateParameterDepthRAII CurTemplateDepthTracker(
950 TemplateParameterDepth);
951 ++CurTemplateDepthTracker;
962 Depth, Position, EqualLoc,
966 void Parser::DiagnoseMisplacedEllipsis(
SourceLocation EllipsisLoc,
968 bool AlreadyHasEllipsis,
969 bool IdentifierHasName) {
971 if (!AlreadyHasEllipsis)
973 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
975 << !IdentifierHasName;
978 void Parser::DiagnoseMisplacedEllipsisInDeclarator(
SourceLocation EllipsisLoc,
982 if (!AlreadyHasEllipsis)
985 AlreadyHasEllipsis, D.
hasName());
1003 bool Parser::ParseGreaterThanInTemplateList(
SourceLocation LAngleLoc,
1005 bool ConsumeLastToken,
1006 bool ObjCGenericList) {
1009 const char *ReplacementStr =
"> >";
1010 bool MergeWithNextToken =
false;
1015 Diag(LAngleLoc, diag::note_matching) << tok::less;
1022 if (ConsumeLastToken)
1026 case tok::greatergreater:
1027 RemainingToken = tok::greater;
1030 case tok::greatergreatergreater:
1031 RemainingToken = tok::greatergreater;
1034 case tok::greaterequal:
1035 RemainingToken = tok::equal;
1036 ReplacementStr =
"> =";
1043 RemainingToken = tok::equalequal;
1044 MergeWithNextToken =
true;
1048 case tok::greatergreaterequal:
1049 RemainingToken = tok::greaterequal;
1068 bool PreventMergeWithNextToken =
1069 (RemainingToken == tok::greater ||
1070 RemainingToken == tok::greatergreater) &&
1071 (Next.isOneOf(tok::greater, tok::greatergreater,
1072 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1073 tok::greatergreaterequal, tok::equalequal)) &&
1074 areTokensAdjacent(Tok, Next);
1077 if (!ObjCGenericList) {
1092 if (PreventMergeWithNextToken)
1095 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1097 (Tok.
is(tok::greatergreater) || Tok.
is(tok::greatergreatergreater)))
1098 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1099 else if (Tok.
is(tok::greaterequal))
1100 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1101 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1112 RAngleLoc = PP.
SplitToken(TokLoc, GreaterLength);
1118 Greater.setLocation(RAngleLoc);
1119 Greater.setKind(tok::greater);
1120 Greater.setLength(GreaterLength);
1123 if (MergeWithNextToken) {
1129 Tok.
setLength(OldLength - GreaterLength);
1134 if (PreventMergeWithNextToken)
1139 if (CachingTokens) {
1141 if (MergeWithNextToken)
1144 if (ConsumeLastToken)
1150 if (ConsumeLastToken) {
1151 PrevTokLocation = RAngleLoc;
1153 PrevTokLocation = TokBeforeGreaterLoc;
1172 bool Parser::ParseTemplateIdAfterTemplateName(
bool ConsumeLastToken,
1174 TemplateArgList &TemplateArgs,
1176 TemplateTy Template) {
1177 assert(Tok.
is(tok::less) &&
"Must have already parsed the template-name");
1186 if (!Tok.
isOneOf(tok::greater, tok::greatergreater,
1187 tok::greatergreatergreater, tok::greaterequal,
1188 tok::greatergreaterequal))
1189 Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);
1194 SkipUntil(tok::greater, tok::greatergreater,
1201 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1247 bool Parser::AnnotateTemplateIdToken(TemplateTy Template,
TemplateNameKind TNK,
1251 bool AllowTypeAnnotation,
1255 "Parser isn't at the beginning of a template-id");
1256 assert(!(
TypeConstraint && AllowTypeAnnotation) &&
"type-constraint can't be "
1257 "a type annotation");
1259 "must accompany a concept name");
1267 TemplateArgList TemplateArgs;
1268 bool ArgsInvalid =
false;
1270 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1271 false, LAngleLoc, TemplateArgs, RAngleLoc, Template);
1286 : Actions.ActOnTemplateIdType(
1289 LAngleLoc, TemplateArgsPtr, RAngleLoc);
1291 Tok.
setKind(tok::annot_typename);
1292 setTypeAnnotation(Tok,
Type);
1295 else if (TemplateKWLoc.
isValid())
1302 Tok.
setKind(tok::annot_template_id);
1315 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1316 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1349 void Parser::AnnotateTemplateIdTokenAsType(
1352 assert(Tok.
is(tok::annot_template_id) &&
"Requires template-id tokens");
1356 "Only works for type and dependent templates");
1364 : Actions.ActOnTemplateIdType(
1366 TemplateId->Template, TemplateId->Name,
1367 TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1368 TemplateArgsPtr, TemplateId->RAngleLoc,
1369 false, IsClassName, AllowImplicitTypename);
1371 Tok.
setKind(tok::annot_typename);
1372 setTypeAnnotation(Tok,
Type);
1385 return Tok.
isOneOf(tok::comma, tok::greater, tok::greatergreater,
1386 tok::greatergreatergreater);
1391 if (!Tok.
is(tok::identifier) && !Tok.
is(tok::coloncolon) &&
1392 !Tok.
is(tok::annot_cxxscope))
1407 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1413 if (SS.
isSet() && Tok.
is(tok::kw_template)) {
1418 if (Tok.
is(tok::identifier)) {
1436 }
else if (Tok.
is(tok::identifier)) {
1446 bool MemberOfUnknownSpecialization;
1451 false, Template, MemberOfUnknownSpecialization);
1461 if (EllipsisLoc.
isValid() && !Result.isInvalid())
1490 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1498 TentativeParsingAction TPA(*
this);
1501 = ParseTemplateTemplateArgument();
1502 if (!TemplateTemplateArgument.
isInvalid()) {
1504 return TemplateTemplateArgument;
1515 ExprArg = ParseBraceInitializer();
1534 bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1535 TemplateTy Template,
1540 auto RunSignatureHelp = [&] {
1543 CalledSignatureHelp =
true;
1545 Template, TemplateArgs, OpenLoc);
1562 TemplateArgs.push_back(Arg);
1585 ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);
1586 return ParseDeclarationAfterTemplate(
1587 Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1593 TemplateParams->size());
1596 if (ExternLoc.isValid())
1597 R.setBegin(ExternLoc);
1602 ((
Parser *)
P)->ParseLateTemplatedFuncDef(LPT);
1611 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*
this);
1616 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1622 MultiParseScope Scopes(*
this);
1627 DC = DC->getLexicalParent())
1628 DeclContextsToReenter.push_back(DC);
1631 for (
DeclContext *DC : reverse(DeclContextsToReenter)) {
1632 CurTemplateDepthTracker.addDepth(
1645 assert(!LPT.
Toks.empty() &&
"Empty body!");
1649 LPT.
Toks.push_back(Tok);
1650 PP.EnterTokenStream(LPT.
Toks,
true,
true);
1654 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
1655 "Inline method not starting with '{', ':' or 'try'");
1667 if (Tok.
is(tok::kw_try)) {
1668 ParseFunctionTryBlock(LPT.
D, FnScope);
1670 if (Tok.
is(tok::colon))
1671 ParseConstructorInitializer(LPT.
D);
1675 if (Tok.
is(tok::l_brace)) {
1676 assert((!isa<FunctionTemplateDecl>(LPT.
D) ||
1677 cast<FunctionTemplateDecl>(LPT.
D)
1678 ->getTemplateParameters()
1679 ->getDepth() == TemplateParameterDepth - 1) &&
1680 "TemplateParameterDepth should be greater than the depth of "
1681 "current template being instantiated!");
1682 ParseFunctionStatementBody(LPT.
D, FnScope);
1690 void Parser::LexTemplateFunctionForLateParsing(
CachedTokens &Toks) {
1692 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1694 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1698 if (
kind == tok::kw_try) {
1699 while (Tok.
is(tok::kw_catch)) {
1700 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
1701 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1711 TentativeParsingAction TPA(*
this);
1713 if (
SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1718 ParseGreaterThanInTemplateList(Less, Greater,
true,
false);
1730 void Parser::checkPotentialAngleBracket(
ExprResult &PotentialTemplateName) {
1731 assert(Tok.
is(tok::less) &&
"not at a potential angle bracket");
1747 ParseGreaterThanInTemplateList(Less, Greater,
true,
false);
1749 getCurScope(), PotentialTemplateName, Less, Greater);
1759 TentativeParsingAction TPA(*
this);
1761 if (isTypeIdUnambiguously() &&
1762 diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {
1775 : AngleBracketTracker::PotentialTypo) |
1777 : AngleBracketTracker::NoSpaceBeforeLess);
1778 AngleBrackets.add(*
this, PotentialTemplateName.
get(), Tok.
getLocation(),
1782 bool Parser::checkPotentialAngleBracketDelimiter(
1787 if (OpToken.
is(tok::comma) && isTypeIdUnambiguously() &&
1788 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1789 AngleBrackets.clear(*
this);
1796 if (OpToken.
is(tok::greater) && Tok.
is(tok::l_paren) &&
1799 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1801 AngleBrackets.clear(*
this);
1807 if (OpToken.
is(tok::greater) ||
1809 OpToken.
isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1810 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.
constexpr static 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...
bool isTranslationUnit() const
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
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.
SourceLocation getBeginLoc() const LLVM_READONLY
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)
AttributeFactory & getAttrFactory()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
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.
Scope * getCurScope() const
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
const LangOptions & getLangOpts() 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 ...
friend class ObjCDeclContextSwitch
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
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.
SourceManager & getSourceManager() const
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...
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)
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)
Decl * ActOnConceptDefinition(Scope *S, MultiTemplateParamsArg TemplateParameterLists, const IdentifierInfo *Name, SourceLocation NameLoc, 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)
Scope * getCurScope() const
Retrieve the parser's current scope.
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)
SemaCodeCompletion & CodeCompletion()
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.
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 * getAnnotationValue() const
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)) {....
tok::TokenKind getKind() const
IdentifierInfo * getIdentifierInfo() 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.
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.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.
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.
bool mightBeType() const
Determine whether this might be a type template.