22#include "llvm/ADT/ScopeExit.h"
27 if (!Tok.is(tok::l_paren))
29 StringLiteral *
Message =
nullptr;
33 if (isTokenStringLiteral()) {
41 Diag(Tok.getLocation(), diag::err_expected_string_literal)
50void Parser::SkipDeletedFunctionBody() {
51 if (!Tok.is(tok::l_paren))
59 if (Tok.is(tok::r_paren))
63NamedDecl *Parser::ParseCXXInlineMethodDef(
68 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&
69 "Current token not a '{', ':', '=', or 'try'!");
72 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
74 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
78 FnD = Actions.ActOnFriendFunctionDecl(
getCurScope(), D,
81 FnD = Actions.ActOnCXXMemberDeclarator(
getCurScope(), AS, D,
82 TemplateParams,
nullptr,
85 Actions.ProcessDeclAttributeList(
getCurScope(), FnD, AccessAttrs);
87 Actions.ActOnPureSpecifier(FnD, PureSpecLoc);
92 HandleMemberFunctionDeclDelays(D, FnD);
103 SourceLocation KWLoc;
105 DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
107 StringLiteral *
Message = ParseCXXDeletedFunctionMessage();
108 Actions.SetDeclDeleted(FnD, KWLoc, Message);
110 if (
auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
111 DeclAsFunction->setRangeEnd(PrevTokLocation);
114 DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
116 Actions.SetDeclDefaulted(FnD, KWLoc);
117 if (
auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
118 DeclAsFunction->setRangeEnd(PrevTokLocation);
121 llvm_unreachable(
"function definition after = not 'delete' or 'default'");
124 if (Tok.is(tok::comma)) {
125 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
128 }
else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
129 Delete ?
"delete" :
"default") &&
130 !isLikelyAtStartOfNewDeclaration()) {
137 if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) &&
138 trySkippingFunctionBody()) {
139 Actions.ActOnSkippedFunctionBody(FnD);
151 ((Actions.CurContext->isDependentContext() ||
154 !Actions.IsInsideALocalClassWithinATemplateFunction())) {
157 LexTemplateFunctionForLateParsing(Toks);
161 Actions.CheckForFunctionRedefinition(FD);
162 Actions.MarkAsLateParsedTemplate(FD, FnD, Toks);
170 LexedMethod* LM =
new LexedMethod(
this, FnD);
171 getCurrentClass().LateParsedDeclarations.push_back(LM);
177 if (ConsumeAndStoreFunctionPrologue(Toks)) {
183 if (PP.isCodeCompletionEnabled() &&
184 llvm::any_of(Toks, [](
const Token &Tok) {
185 return Tok.is(tok::code_completion);
198 delete getCurrentClass().LateParsedDeclarations.back();
199 getCurrentClass().LateParsedDeclarations.pop_back();
203 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
207 if (
kind == tok::kw_try) {
208 while (Tok.is(tok::kw_catch)) {
209 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
210 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
218 Actions.CheckForFunctionRedefinition(FD);
223 delete getCurrentClass().LateParsedDeclarations.back();
224 getCurrentClass().LateParsedDeclarations.pop_back();
230void Parser::ParseCXXNonStaticMemberInitializer(
Decl *VarD) {
231 assert(Tok.isOneOf(tok::l_brace, tok::equal) &&
232 "Current token not a '{' or '='!");
234 LateParsedMemberInitializer *MI =
235 new LateParsedMemberInitializer(
this, VarD);
236 getCurrentClass().LateParsedDeclarations.push_back(MI);
240 if (
kind == tok::equal) {
245 if (
kind == tok::l_brace) {
251 ConsumeAndStoreUntil(tok::r_brace, Toks,
true);
270Parser::LateParsedClass::LateParsedClass(
Parser *P, ParsingClass *
C)
273Parser::LateParsedClass::~LateParsedClass() {
274 Self->DeallocateParsedClasses(Class);
278 Self->ParseLexedMethodDeclarations(*
Class);
282 Self->ParseLexedMemberInitializers(*
Class);
298 Self->ParseLexedMethodDeclaration(*
this);
302 Self->ParseLexedMethodDef(*
this);
306 Self->ParseLexedMemberInitializer(*
this);
310 Self->ParseLexedAttribute(*
this,
true,
false);
316 Self->ParseLexedPragma(*
this);
328 P.ReenterTemplateScopes(
Scopes, MaybeTemplated));
338 !
Class.TopLevelClass),
341 if (
Class.TopLevelClass)
346 P.Actions.ActOnStartDelayedMemberDeclarations(
P.getCurScope(),
347 Class.TagOrTemplate);
350 if (
Class.TopLevelClass)
353 P.Actions.ActOnFinishDelayedMemberDeclarations(
P.getCurScope(),
354 Class.TagOrTemplate);
358void Parser::ParseLexedMethodDeclarations(ParsingClass &
Class) {
359 ReenterClassScopeRAII InClassScope(*
this,
Class);
365void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
367 ReenterTemplateScopeRAII InFunctionTemplateScope(*
this, LM.Method);
391 for (
unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
394 bool HasUnparsed = Param->hasUnparsedDefaultArg();
396 std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks);
402 Token LastDefaultArgToken = Toks->back();
405 Toks->push_back(DefArgEnd);
408 Toks->push_back(
Tok);
409 PP.EnterTokenStream(*Toks,
true,
true);
415 assert(
Tok.is(tok::equal) &&
"Default argument not starting with '='");
426 Diag(
Tok, diag::compat_cxx11_generalized_initializer_lists);
427 DefArgResult = ParseBraceInitializer();
431 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
434 if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {
438 assert(Toks->size() >= 3 &&
"expected a token in default arg");
439 Diag(Tok.getLocation(), diag::err_default_arg_unparsed)
440 << SourceRange(Tok.getLocation(),
441 (*Toks)[Toks->size() - 3].getLocation());
443 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
449 while (Tok.isNot(tok::eof))
452 if (Tok.is(tok::eof) && Tok.getEofData() == Param)
454 }
else if (HasUnparsed) {
455 assert(Param->hasInheritedDefaultArg());
457 if (
const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method))
466 Param->setUninstantiatedDefaultArg(
469 Param->setDefaultArg(OldParam->
getInit());
479 Token LastExceptionSpecToken = Toks->back();
480 Token ExceptionSpecEnd =
482 Toks->push_back(ExceptionSpecEnd);
485 Toks->push_back(Tok);
486 PP.EnterTokenStream(*Toks,
true,
true);
498 FunctionDecl *FunctionToPush;
499 if (FunctionTemplateDecl *FunTmpl
500 = dyn_cast<FunctionTemplateDecl>(LM.Method))
501 FunctionToPush = FunTmpl->getTemplatedDecl();
504 Method = dyn_cast<CXXMethodDecl>(FunctionToPush);
509 Sema::ContextRAII FnContext(Actions, FunctionToPush,
512 Sema::CXXThisScopeRAII ThisScope(
518 SourceRange SpecificationRange;
519 SmallVector<ParsedType, 4> DynamicExceptions;
520 SmallVector<SourceRange, 4> DynamicExceptionRanges;
525 = tryParseExceptionSpecification(
false, SpecificationRange,
527 DynamicExceptionRanges, NoexceptExpr,
528 ExceptionSpecTokens);
530 if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)
531 Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
534 Actions.actOnDelayedExceptionSpecification(LM.Method, EST,
537 DynamicExceptionRanges,
539 NoexceptExpr.
get() :
nullptr);
543 while (Tok.isNot(tok::eof))
547 if (Tok.is(tok::eof) && Tok.getEofData() == LM.Method)
551 LM.ExceptionSpecTokens =
nullptr;
554 InFunctionTemplateScope.Scopes.Exit();
557 Actions.ActOnFinishDelayedCXXMethodDeclaration(
getCurScope(), LM.Method);
560void Parser::ParseLexedMethodDefs(ParsingClass &
Class) {
563 for (LateParsedDeclaration *D :
Class.LateParsedDeclarations)
567void Parser::ParseLexedMethodDef(LexedMethod &LM) {
573 assert(!LM.Toks.empty() &&
"Empty body!");
574 Token LastBodyToken = LM.Toks.back();
576 LM.Toks.push_back(BodyEnd);
579 LM.Toks.push_back(Tok);
580 PP.EnterTokenStream(LM.Toks,
true,
true);
584 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)
585 &&
"Inline method not starting with '{', ':' or 'try'");
591 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
593 Actions.ActOnStartOfFunctionDef(
getCurScope(), LM.D);
595 llvm::scope_exit _([&]() {
596 while (Tok.isNot(tok::eof))
599 if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
602 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
605 Actions.ActOnFinishInlineFunctionDef(FD);
608 assert((Actions.getDiagnostics().hasErrorOccurred() ||
611 < TemplateParameterDepth) &&
612 "TemplateParameterDepth should be greater than the depth of "
613 "current template being instantiated!");
615 ParseFunctionBody(LM.D, FnScope);
618void Parser::ParseLexedMemberInitializers(ParsingClass &
Class) {
621 if (!
Class.LateParsedDeclarations.empty()) {
628 Sema::CXXThisScopeRAII ThisScope(Actions,
Class.TagOrTemplate,
631 for (LateParsedDeclaration *D :
Class.LateParsedDeclarations)
635 Actions.ActOnFinishDelayedMemberInitializers(
Class.TagOrTemplate);
638void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
639 if (!MI.Field || MI.Field->isInvalidDecl())
646 MI.Toks.push_back(Tok);
647 PP.EnterTokenStream(MI.Toks,
true,
true);
652 SourceLocation EqualLoc;
654 Actions.ActOnStartCXXInClassMemberInitializer();
658 EnterExpressionEvaluationContext Eval(
664 Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc,
Init);
667 if (Tok.isNot(tok::eof)) {
668 if (!
Init.isInvalid()) {
669 SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
671 EndLoc = Tok.getLocation();
673 Diag(EndLoc, diag::err_expected_semi_decl_list);
677 while (Tok.isNot(tok::eof))
681 if (Tok.getEofData() == MI.Field)
685void Parser::ParseLexedAttributes(ParsingClass &
Class) {
688 for (LateParsedDeclaration *LateD :
Class.LateParsedDeclarations)
692void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
694 ParsedAttributes *OutAttrs) {
696 "Attribute list should be marked for immediate parsing.");
697 for (
unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
700 ParseLexedAttribute(*LAs[i],
EnterScope, OnDefinition, OutAttrs);
711 for (
unsigned I = 0, E = AL.getNumArgs(); I != E; ++I)
713 Worklist.push_back(AL.getArgAsExpr(I));
714 while (!Worklist.empty()) {
715 const Stmt *S = Worklist.pop_back_val();
718 if (
const auto *DRE = dyn_cast<DeclRefExpr>(S);
721 llvm::append_range(Worklist, S->
children());
725bool Parser::checkLateAttributeParamRefs(
727 ArrayRef<const DeclRefExpr *> ParamRefs,
bool ReenteredProtoParams) {
728 auto IsPointeeParam = [&](
const ParmVarDecl *PVD) {
729 return ReenteredProtoParams && llvm::is_contained(LPA.
ProtoParams, PVD);
737 for (
const DeclRefExpr *DRE : ParamRefs) {
739 if (!IsPointeeParam(PVD))
741 LookupResult
R(Actions, PVD->getDeclName(), DRE->getLocation(),
743 if (!Actions.LookupName(R,
getCurScope()) ||
R.isAmbiguous())
745 Diag(DRE->getLocation(), diag::err_ambiguous_reference)
746 << PVD->getDeclName();
747 Diag(PVD->getLocation(), diag::note_ambiguous_candidate) << PVD;
748 for (
const NamedDecl *
Other : R)
749 Diag(
Other->getLocation(), diag::note_ambiguous_candidate) <<
Other;
760 if (Actions.CurContext->isDependentContext() ||
762 Actions.getCurGenericLambda()) {
763 const auto *DParam = dyn_cast_or_null<ParmVarDecl>(D);
764 for (
const DeclRefExpr *DRE : ParamRefs) {
766 bool Pointee = IsPointeeParam(PVD);
769 DParam->getFunctionScopeDepth() == PVD->getFunctionScopeDepth() &&
770 DParam->getFunctionScopeIndex() < PVD->getFunctionScopeIndex()))
772 Diag(DRE->getLocation(), diag::err_late_attribute_param_in_template)
773 << &LPA.
AttrName << !Pointee << PVD;
782 ParsedAttributes *OutAttrs) {
783 ParsedAttributes Attrs(AttrFactory);
785 if (LPA.
Decls.size() > 0) {
791 NamedDecl *ND = dyn_cast<NamedDecl>(D);
792 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->
getDeclContext());
795 Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),
806 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
815 bool HasProtoParams = !HasFuncScope && !LPA.
ProtoParams.empty();
819 HasProtoParams && !InCStruct);
821 Actions.ActOnReenterFunctionPrototypeParams(Actions.getCurScope(),
824 ParsedAttributes Parsed = ParseLexedAttributeTokens(LPA);
826 if (HasProtoParams && InCStruct)
827 Actions.ActOnExitFunctionPrototypeParams(Actions.getCurScope(),
831 SmallVector<const DeclRefExpr *, 4> ParamRefs;
833 if (!ParamRefs.empty() &&
834 checkLateAttributeParamRefs(LPA, D, ParamRefs, HasProtoParams))
836 Attrs.takeAllAppendingFrom(Parsed);
839 Actions.ActOnExitFunctionContext();
845 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
846 Attrs.begin()->isKnownToGCC())
847 Diag(Tok, diag::warn_attribute_on_function_definition) << &LPA.
AttrName;
849 for (
auto *D : LPA.
Decls)
850 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
856void Parser::ParseLexedPragmas(ParsingClass &
Class) {
859 for (LateParsedDeclaration *D :
Class.LateParsedDeclarations)
863void Parser::ParseLexedPragma(LateParsedPragma &LP) {
864 PP.EnterToken(Tok,
true);
865 PP.EnterTokenStream(LP.toks(),
true,
870 assert(Tok.isAnnotation() &&
"Expected annotation token.");
871 switch (Tok.getKind()) {
872 case tok::annot_attr_openmp:
873 case tok::annot_pragma_openmp: {
875 ParsedAttributes Attrs(AttrFactory);
876 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
880 llvm_unreachable(
"Unexpected token.");
889 bool isFirstTokenConsumed =
true;
892 if (Tok.is(T1) || Tok.is(T2)) {
893 if (ConsumeFinalToken) {
900 switch (Tok.getKind()) {
902 case tok::annot_module_begin:
903 case tok::annot_module_end:
904 case tok::annot_module_include:
905 case tok::annot_repl_input_end:
909 case tok::annot_pragma_openacc:
910 case tok::annot_pragma_openmp:
911 case tok::annot_attr_openmp: {
915 ? tok::annot_pragma_openacc_end
916 : tok::annot_pragma_openmp_end;
918 ConsumeAnnotationToken();
919 while (Tok.isNot(EndKind) && Tok.isNot(tok::eof)) {
923 if (Tok.is(EndKind)) {
925 ConsumeAnnotationToken();
934 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
940 ConsumeAndStoreUntil(tok::r_square, Toks,
false);
946 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
955 if (ParenCount && !isFirstTokenConsumed)
961 if (BracketCount && !isFirstTokenConsumed)
967 if (BraceCount && !isFirstTokenConsumed)
983 isFirstTokenConsumed =
false;
987bool Parser::ConsumeAndStoreFunctionPrologue(
CachedTokens &Toks) {
988 if (Tok.is(tok::kw_try)) {
993 if (Tok.isNot(tok::colon)) {
999 ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
1002 if (Tok.isNot(tok::l_brace))
1003 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
1005 Toks.push_back(Tok);
1010 Toks.push_back(Tok);
1023 bool MightBeTemplateArgument =
false;
1027 if (Tok.is(tok::kw_decltype)) {
1028 Toks.push_back(Tok);
1030 if (Tok.isNot(tok::l_paren))
1031 return Diag(Tok.getLocation(), diag::err_expected_lparen_after)
1033 Toks.push_back(Tok);
1035 if (!ConsumeAndStoreUntil(tok::r_paren, Toks,
true)) {
1036 Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1037 Diag(OpenLoc, diag::note_matching) << tok::l_paren;
1043 if (Tok.is(tok::coloncolon)) {
1044 Toks.push_back(Tok);
1047 if (Tok.is(tok::kw_template)) {
1048 Toks.push_back(Tok);
1053 if (Tok.is(tok::identifier)) {
1054 Toks.push_back(Tok);
1060 if (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::l_square)) {
1061 Toks.push_back(Tok);
1063 Toks.push_back(Tok);
1065 if (!ConsumeAndStoreUntil(tok::r_square, Toks,
true)) {
1066 Diag(Tok.getLocation(), diag::err_expected) << tok::r_square;
1067 Diag(OpenLoc, diag::note_matching) << tok::l_square;
1072 }
while (Tok.is(tok::coloncolon));
1074 if (Tok.is(tok::code_completion)) {
1075 Toks.push_back(Tok);
1076 ConsumeCodeCompletionToken();
1077 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)) {
1084 if (Tok.is(tok::comma)) {
1086 Toks.push_back(Tok);
1090 if (Tok.is(tok::less))
1091 MightBeTemplateArgument =
true;
1093 if (MightBeTemplateArgument) {
1100 if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
1105 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
1107 }
else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) {
1110 return Diag(Tok.getLocation(), diag::err_expected_either)
1111 << tok::l_paren << tok::l_brace;
1113 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
1117 Toks.push_back(Tok);
1118 bool IsLParen = (
kind == tok::l_paren);
1119 SourceLocation OpenLoc = Tok.getLocation();
1124 assert(
kind == tok::l_brace &&
"Must be left paren or brace here.");
1131 const Token &PreviousToken = Toks[Toks.size() - 2];
1132 if (!MightBeTemplateArgument &&
1133 !PreviousToken.
isOneOf(tok::identifier, tok::greater,
1134 tok::greatergreater)) {
1140 TentativeParsingAction PA(*
this);
1142 !Tok.isOneOf(tok::comma, tok::ellipsis, tok::l_brace)) {
1155 tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;
1156 if (!ConsumeAndStoreUntil(CloseKind, Toks,
true)) {
1157 Diag(Tok, diag::err_expected) << CloseKind;
1158 Diag(OpenLoc, diag::note_matching) <<
kind;
1163 if (Tok.is(tok::ellipsis)) {
1164 Toks.push_back(Tok);
1170 if (Tok.is(tok::comma)) {
1171 Toks.push_back(Tok);
1173 }
else if (Tok.is(tok::l_brace)) {
1188 Toks.push_back(Tok);
1191 }
else if (!MightBeTemplateArgument) {
1192 return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
1198bool Parser::ConsumeAndStoreConditional(
CachedTokens &Toks) {
1200 assert(Tok.is(tok::question));
1201 Toks.push_back(Tok);
1204 while (Tok.isNot(tok::colon)) {
1205 if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks,
1211 if (Tok.is(tok::question) && !ConsumeAndStoreConditional(Toks))
1216 Toks.push_back(Tok);
1221bool Parser::ConsumeAndStoreInitializer(
CachedTokens &Toks,
1224 bool IsFirstToken =
true;
1229 unsigned AngleCount = 0;
1230 unsigned KnownTemplateCount = 0;
1233 switch (Tok.getKind()) {
1237 if (ParenCount == 1 &&
NextToken().
is(tok::r_paren))
1245 if (KnownTemplateCount)
1258 TentativeParsingAction TPA(*
this,
true);
1259 Sema::TentativeAnalysisScope Scope(Actions);
1261 TPResult
Result = TPResult::Error;
1265 Result = TryParseInitDeclaratorList();
1268 if (
Result == TPResult::Ambiguous && Tok.isNot(tok::semi))
1269 Result = TPResult::False;
1273 bool InvalidAsDeclaration =
false;
1274 Result = TryParseParameterDeclarationClause(
1275 &InvalidAsDeclaration,
true);
1278 if (
Result == TPResult::Ambiguous && InvalidAsDeclaration)
1279 Result = TPResult::False;
1289 if (
Result != TPResult::False &&
Result != TPResult::Error)
1294 ++KnownTemplateCount;
1310 if (!ConsumeAndStoreConditional(Toks))
1314 case tok::greatergreatergreater:
1317 if (AngleCount) --AngleCount;
1318 if (KnownTemplateCount) --KnownTemplateCount;
1320 case tok::greatergreater:
1323 if (AngleCount) --AngleCount;
1324 if (KnownTemplateCount) --KnownTemplateCount;
1327 if (AngleCount) --AngleCount;
1328 if (KnownTemplateCount) --KnownTemplateCount;
1331 case tok::kw_template:
1335 Toks.push_back(Tok);
1337 if (Tok.is(tok::identifier)) {
1338 Toks.push_back(Tok);
1340 if (Tok.is(tok::less)) {
1342 ++KnownTemplateCount;
1343 Toks.push_back(Tok);
1349 case tok::kw_operator:
1352 Toks.push_back(Tok);
1354 switch (Tok.getKind()) {
1356 case tok::greatergreatergreater:
1357 case tok::greatergreater:
1360 Toks.push_back(Tok);
1370 Toks.push_back(Tok);
1372 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
1376 Toks.push_back(Tok);
1378 ConsumeAndStoreUntil(tok::r_square, Toks,
false);
1382 Toks.push_back(Tok);
1384 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1396 if (ParenCount && !IsFirstToken)
1398 Toks.push_back(Tok);
1402 if (BracketCount && !IsFirstToken)
1404 Toks.push_back(Tok);
1408 if (BraceCount && !IsFirstToken)
1410 Toks.push_back(Tok);
1414 case tok::code_completion:
1415 Toks.push_back(Tok);
1416 ConsumeCodeCompletionToken();
1419 case tok::string_literal:
1420 case tok::wide_string_literal:
1421 case tok::utf8_string_literal:
1422 case tok::utf16_string_literal:
1423 case tok::utf32_string_literal:
1424 Toks.push_back(Tok);
1425 ConsumeStringToken();
1435 if (Tok.isAnnotation())
1438 Toks.push_back(Tok);
1442 IsFirstToken =
false;
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static void collectParamRefs(const ParsedAttributes &Attrs, SmallVectorImpl< const DeclRefExpr * > &Refs)
Collect the references to parameters in Attrs' arguments.
FriendSpecified isFriendSpecified() const
bool hasConstexprSpecifier() const
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
bool isInIdentifierNamespace(unsigned NS) const
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
@ IDNS_OrdinaryFriend
This declaration is a friend function.
DeclContext * getDeclContext()
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
FunctionDefinitionKind getFunctionDefinitionKind() const
RAII object that enters a new expression evaluation context.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getReturnType() const
void setWillHaveBody(bool V=true)
StringRef getName() const
Return the actual identifier string.
[class.mem]p1: "... the class is regarded as complete within
virtual ~LateParsedDeclaration()
virtual void ParseLexedMethodDefs()
virtual void ParseLexedAttributes()
virtual void ParseLexedPragmas()
virtual void ParseLexedMethodDeclarations()
virtual void ParseLexedMemberInitializers()
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
bool hasUninstantiatedDefaultArg() const
Expr * getUninstantiatedDefaultArg()
ParsedAttr - Represents a syntactic attribute.
ParsedAttributes - A collection of parsed attributes.
void takeAllAppendingFrom(ParsedAttributes &Other)
Introduces zero or more scopes for parsing.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
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
friend struct LateParsedAttribute
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 ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
A class for parsing a declarator.
const ParsingDeclSpec & getDeclSpec() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ 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.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
void PushFunctionScope()
Enter a new function scope.
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method)
ActOnStartDelayedCXXMethodDeclaration - We have completed parsing a top-level (non-nested) C++ class,...
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param)
ActOnDelayedCXXMethodParameter - We've already started a delayed C++ method declaration.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
static Token createEof(SourceLocation Loc=SourceLocation(), const void *Data=nullptr)
bool isOneOf(Ts... Ks) const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
const Expr * getInit() const
Represents a C++11 virt-specifier-seq.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
@ ICIS_NoInit
No in-class initializer.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ Result
The result type of a method or function.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ NonTemplate
We are not parsing a template at all.
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
ReenterClassScopeRAII(Parser &P, ParsingClass &Class)
ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter=true)
TemplateParameterDepthRAII CurTemplateDepthTracker
SmallVector< ParmVarDecl *, 4 > ProtoParams
Parameters of the prototype the attribute was written on, kept because late parsing runs after their ...
IdentifierInfo & AttrName
void ParseLexedAttributes() override
SourceLocation AttrNameLoc
SmallVector< Decl *, 2 > Decls
void ParseLexedAttributes() override
An RAII helper that pops function a function scope on exit.