24#include "llvm/ADT/STLExtras.h"
36 ParsedStmtContext StmtCtx) {
43 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
99Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
100 ParsedStmtContext StmtCtx,
111 MaybeParseCXX11Attributes(CXX11Attrs,
true);
114 MaybeParseGNUAttributes(GNUAttrs);
116 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
117 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUAttrs);
118 MaybeDestroyTemplateIds();
126 "attributes on empty statement");
137 StatementFilterCCC(
Token nextTok) : NextToken(nextTok) {
138 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
139 tok::identifier, tok::star, tok::amp);
140 WantExpressionKeywords =
141 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
142 WantRemainingKeywords =
143 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
144 WantCXXNamedCasts =
false;
147 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
150 if (NextToken.is(tok::equal))
152 if (NextToken.is(tok::period) &&
158 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
159 return std::make_unique<StatementFilterCCC>(*
this);
167StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
168 StmtVector &Stmts, ParsedStmtContext StmtCtx,
171 const char *SemiError =
nullptr;
185 return ParseObjCAtStatement(AtLoc, StmtCtx);
188 case tok::code_completion:
193 case tok::identifier:
196 if (Next.is(tok::colon)) {
204 return ParseLabeledStatement(Attrs, StmtCtx);
209 if (Next.isNot(tok::coloncolon)) {
212 StatementFilterCCC CCC(Next);
213 if (TryAnnotateName(&CCC) == ANK_Error) {
217 if (Tok.
is(tok::semi))
223 if (Tok.
isNot(tok::identifier))
232 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
234 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
235 llvm::all_of(GNUAttrs, IsStmtAttr);
237 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
238 ParsedStmtContext()) &&
239 ((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
240 isDeclarationStatement())) {
243 if (GNUAttributeLoc.
isValid()) {
244 DeclStart = GNUAttributeLoc;
246 GNUAttrs, &GNUAttributeLoc);
262 if (Tok.
is(tok::r_brace)) {
263 Diag(Tok, diag::err_expected_statement);
268#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
269#include "clang/Basic/TransformTypeTraits.def"
272 Diag(Tok, diag::ext_keyword_as_ident)
274 goto ParseIdentifier;
278 return ParseExprStatement(StmtCtx);
282 case tok::kw___attribute: {
284 ParseGNUAttributes(GNUAttrs);
289 return ParseCaseStatement(StmtCtx);
290 case tok::kw_default:
291 return ParseDefaultStatement(StmtCtx);
294 return ParseCompoundStatement();
301 return ParseIfStatement(TrailingElseLoc);
303 return ParseSwitchStatement(TrailingElseLoc);
306 return ParseWhileStatement(TrailingElseLoc);
308 Res = ParseDoStatement();
309 SemiError =
"do/while";
312 return ParseForStatement(TrailingElseLoc);
315 Res = ParseGotoStatement();
318 case tok::kw_continue:
319 Res = ParseContinueStatement();
320 SemiError =
"continue";
323 Res = ParseBreakStatement();
327 Res = ParseReturnStatement();
328 SemiError =
"return";
330 case tok::kw_co_return:
331 Res = ParseReturnStatement();
332 SemiError =
"co_return";
337 Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
340 ProhibitAttributes(GNUAttrs);
342 Res = ParseAsmStatement(msAsm);
343 if (msAsm)
return Res;
348 case tok::kw___if_exists:
349 case tok::kw___if_not_exists:
350 ProhibitAttributes(CXX11Attrs);
351 ProhibitAttributes(GNUAttrs);
352 ParseMicrosoftIfExistsStatement(Stmts);
358 return ParseCXXTryBlock();
361 ProhibitAttributes(CXX11Attrs);
362 ProhibitAttributes(GNUAttrs);
363 return ParseSEHTryBlock();
365 case tok::kw___leave:
366 Res = ParseSEHLeaveStatement();
367 SemiError =
"__leave";
370 case tok::annot_pragma_vis:
371 ProhibitAttributes(CXX11Attrs);
372 ProhibitAttributes(GNUAttrs);
373 HandlePragmaVisibility();
376 case tok::annot_pragma_pack:
377 ProhibitAttributes(CXX11Attrs);
378 ProhibitAttributes(GNUAttrs);
382 case tok::annot_pragma_msstruct:
383 ProhibitAttributes(CXX11Attrs);
384 ProhibitAttributes(GNUAttrs);
385 HandlePragmaMSStruct();
388 case tok::annot_pragma_align:
389 ProhibitAttributes(CXX11Attrs);
390 ProhibitAttributes(GNUAttrs);
394 case tok::annot_pragma_weak:
395 ProhibitAttributes(CXX11Attrs);
396 ProhibitAttributes(GNUAttrs);
400 case tok::annot_pragma_weakalias:
401 ProhibitAttributes(CXX11Attrs);
402 ProhibitAttributes(GNUAttrs);
403 HandlePragmaWeakAlias();
406 case tok::annot_pragma_redefine_extname:
407 ProhibitAttributes(CXX11Attrs);
408 ProhibitAttributes(GNUAttrs);
409 HandlePragmaRedefineExtname();
412 case tok::annot_pragma_fp_contract:
413 ProhibitAttributes(CXX11Attrs);
414 ProhibitAttributes(GNUAttrs);
415 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
416 ConsumeAnnotationToken();
419 case tok::annot_pragma_fp:
420 ProhibitAttributes(CXX11Attrs);
421 ProhibitAttributes(GNUAttrs);
422 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
423 ConsumeAnnotationToken();
426 case tok::annot_pragma_fenv_access:
427 case tok::annot_pragma_fenv_access_ms:
428 ProhibitAttributes(CXX11Attrs);
429 ProhibitAttributes(GNUAttrs);
430 Diag(Tok, diag::err_pragma_file_or_compound_scope)
431 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
433 ConsumeAnnotationToken();
436 case tok::annot_pragma_fenv_round:
437 ProhibitAttributes(CXX11Attrs);
438 ProhibitAttributes(GNUAttrs);
439 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
440 ConsumeAnnotationToken();
443 case tok::annot_pragma_float_control:
444 ProhibitAttributes(CXX11Attrs);
445 ProhibitAttributes(GNUAttrs);
446 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
447 ConsumeAnnotationToken();
450 case tok::annot_pragma_opencl_extension:
451 ProhibitAttributes(CXX11Attrs);
452 ProhibitAttributes(GNUAttrs);
453 HandlePragmaOpenCLExtension();
456 case tok::annot_pragma_captured:
457 ProhibitAttributes(CXX11Attrs);
458 ProhibitAttributes(GNUAttrs);
459 return HandlePragmaCaptured();
461 case tok::annot_pragma_openmp:
464 ProhibitAttributes(CXX11Attrs);
465 ProhibitAttributes(GNUAttrs);
467 case tok::annot_attr_openmp:
469 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
471 case tok::annot_pragma_ms_pointers_to_members:
472 ProhibitAttributes(CXX11Attrs);
473 ProhibitAttributes(GNUAttrs);
474 HandlePragmaMSPointersToMembers();
477 case tok::annot_pragma_ms_pragma:
478 ProhibitAttributes(CXX11Attrs);
479 ProhibitAttributes(GNUAttrs);
480 HandlePragmaMSPragma();
483 case tok::annot_pragma_ms_vtordisp:
484 ProhibitAttributes(CXX11Attrs);
485 ProhibitAttributes(GNUAttrs);
486 HandlePragmaMSVtorDisp();
489 case tok::annot_pragma_loop_hint:
490 ProhibitAttributes(CXX11Attrs);
491 ProhibitAttributes(GNUAttrs);
492 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);
494 case tok::annot_pragma_dump:
498 case tok::annot_pragma_attribute:
499 HandlePragmaAttribute();
508 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
517StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
519 Token OldToken = Tok;
525 if (
Expr.isInvalid()) {
530 if (Tok.
is(tok::semi))
539 Diag(OldToken, diag::err_expected_case_before_expression)
543 return ParseCaseStatement(StmtCtx,
true,
Expr);
547 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
548 return handleExprStmt(
Expr, StmtCtx);
561 assert(Tok.
is(tok::kw___try) &&
"Expected '__try'");
564 if (Tok.
isNot(tok::l_brace))
565 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
570 if (TryBlock.isInvalid())
574 if (Tok.
is(tok::identifier) &&
577 Handler = ParseSEHExceptBlock(Loc);
578 }
else if (Tok.
is(tok::kw___finally)) {
580 Handler = ParseSEHFinallyBlock(Loc);
601 raii2(Ident___exception_code,
false),
602 raii3(Ident_GetExceptionCode,
false);
604 if (ExpectAndConsume(tok::l_paren))
618 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
632 if (ExpectAndConsume(tok::r_paren))
635 if (Tok.
isNot(tok::l_brace))
636 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
640 if(
Block.isInvalid())
653 raii2(Ident___abnormal_termination,
false),
654 raii3(Ident_AbnormalTermination,
false);
656 if (Tok.
isNot(tok::l_brace))
657 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
659 ParseScope FinallyScope(
this, 0);
663 if(
Block.isInvalid()) {
691 ParsedStmtContext StmtCtx) {
693 "Not an identifier!");
697 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
699 Token IdentTok = Tok;
702 assert(Tok.
is(tok::colon) &&
"Not a label!");
709 if (Tok.
is(tok::kw___attribute)) {
711 ParseGNUAttributes(TempAttrs);
725 SubStmt = ParseStatementOrDeclarationAfterAttributes(
726 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs, TempAttrs);
727 if (!TempAttrs.empty() && !SubStmt.
isInvalid())
733 if (SubStmt.
isUnset() && Tok.
is(tok::r_brace)) {
734 DiagnoseLabelAtEndOfCompoundStatement();
740 SubStmt = ParseStatement(
nullptr, StmtCtx);
760StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
762 assert((MissingCase || Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
766 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
789 Stmt *DeepestParsedCaseStmt =
nullptr;
798 if (Tok.
is(tok::code_completion)) {
827 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
835 ColonProtection.restore();
841 Diag(ColonLoc, diag::err_expected_after)
842 <<
"'case'" << tok::colon
846 Diag(ExpectedLoc, diag::err_expected_after)
847 <<
"'case'" << tok::colon
849 ColonLoc = ExpectedLoc;
853 Actions.
ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
858 if (TopLevelCase.isInvalid())
859 return ParseStatement(
nullptr, StmtCtx);
864 Stmt *NextDeepest = Case.
get();
865 if (TopLevelCase.isInvalid())
869 DeepestParsedCaseStmt = NextDeepest;
873 }
while (Tok.
is(tok::kw_case));
878 if (Tok.
is(tok::r_brace)) {
881 DiagnoseLabelAtEndOfCompoundStatement();
884 SubStmt = ParseStatement(
nullptr, StmtCtx);
888 if (DeepestParsedCaseStmt) {
904StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
905 assert(Tok.
is(tok::kw_default) &&
"Not a default stmt!");
909 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
917 Diag(ColonLoc, diag::err_expected_after)
918 <<
"'default'" << tok::colon
922 Diag(ExpectedLoc, diag::err_expected_after)
923 <<
"'default'" << tok::colon
925 ColonLoc = ExpectedLoc;
930 if (Tok.
is(tok::r_brace)) {
933 DiagnoseLabelAtEndOfCompoundStatement();
936 SubStmt = ParseStatement(
nullptr, StmtCtx);
947StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
948 return ParseCompoundStatement(isStmtExpr,
974StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
975 unsigned ScopeFlags) {
976 assert(Tok.
is(tok::l_brace) &&
"Not a compound stmt!");
980 ParseScope CompoundScope(
this, ScopeFlags);
983 return ParseCompoundStatementBody(isStmtExpr);
989void Parser::ParseCompoundStatementLeadingPragmas() {
990 bool checkForPragmas =
true;
991 while (checkForPragmas) {
993 case tok::annot_pragma_vis:
994 HandlePragmaVisibility();
996 case tok::annot_pragma_pack:
999 case tok::annot_pragma_msstruct:
1000 HandlePragmaMSStruct();
1002 case tok::annot_pragma_align:
1003 HandlePragmaAlign();
1005 case tok::annot_pragma_weak:
1008 case tok::annot_pragma_weakalias:
1009 HandlePragmaWeakAlias();
1011 case tok::annot_pragma_redefine_extname:
1012 HandlePragmaRedefineExtname();
1014 case tok::annot_pragma_opencl_extension:
1015 HandlePragmaOpenCLExtension();
1017 case tok::annot_pragma_fp_contract:
1018 HandlePragmaFPContract();
1020 case tok::annot_pragma_fp:
1023 case tok::annot_pragma_fenv_access:
1024 case tok::annot_pragma_fenv_access_ms:
1025 HandlePragmaFEnvAccess();
1027 case tok::annot_pragma_fenv_round:
1028 HandlePragmaFEnvRound();
1030 case tok::annot_pragma_float_control:
1031 HandlePragmaFloatControl();
1033 case tok::annot_pragma_ms_pointers_to_members:
1034 HandlePragmaMSPointersToMembers();
1036 case tok::annot_pragma_ms_pragma:
1037 HandlePragmaMSPragma();
1039 case tok::annot_pragma_ms_vtordisp:
1040 HandlePragmaMSVtorDisp();
1042 case tok::annot_pragma_dump:
1046 checkForPragmas =
false;
1053void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1056 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1057 : diag::ext_cxx_label_end_of_compound_statement);
1060 ? diag::warn_c2x_compat_label_end_of_compound_statement
1061 : diag::ext_c_label_end_of_compound_statement);
1067bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1068 if (!Tok.
is(tok::semi))
1080 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1082 Stmts.push_back(R.
get());
1089 Diag(StartLoc, diag::warn_null_statement)
1095 bool IsStmtExprResult =
false;
1096 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1098 unsigned LookAhead = 0;
1099 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
1105 IsStmtExprResult = GetLookAheadToken(LookAhead).
is(tok::r_brace) &&
1106 GetLookAheadToken(LookAhead + 1).
is(tok::r_paren);
1109 if (IsStmtExprResult)
1118StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1121 "in compound statement ('{}')");
1129 if (T.consumeOpen())
1135 ParseCompoundStatementLeadingPragmas();
1142 while (Tok.
is(tok::kw___label__)) {
1147 if (Tok.
isNot(tok::identifier)) {
1148 Diag(Tok, diag::err_expected) << tok::identifier;
1165 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1167 Stmts.push_back(R.
get());
1170 ParsedStmtContext SubStmtCtx =
1171 ParsedStmtContext::Compound |
1172 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1174 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
1175 Tok.
isNot(tok::eof)) {
1176 if (Tok.
is(tok::annot_pragma_unused)) {
1177 HandlePragmaUnused();
1181 if (ConsumeNullStmt(Stmts))
1185 if (Tok.
isNot(tok::kw___extension__)) {
1186 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1193 while (Tok.
is(tok::kw___extension__))
1197 MaybeParseCXX11Attributes(attrs,
true);
1200 if (isDeclarationStatement()) {
1208 attrs, DeclSpecAttrs);
1212 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1214 if (Res.isInvalid()) {
1221 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1222 R = handleExprStmt(Res, SubStmtCtx);
1229 Stmts.push_back(R.
get());
1240 diag::warn_no_support_for_eval_method_source_on_m32);
1245 if (!T.consumeClose()) {
1248 if (isStmtExpr && Tok.
is(tok::r_paren))
1249 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1255 if (T.getCloseLocation().isValid())
1256 CloseLoc = T.getCloseLocation();
1276bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1287 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1306 if (Tok.
isNot(tok::r_paren))
1312 Start, Tok.
getLocation() == Start ? Start : PrevTokLocation, {},
1321 LParenLoc = T.getOpenLocation();
1322 RParenLoc = T.getCloseLocation();
1327 while (Tok.
is(tok::r_paren)) {
1328 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1338enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1340struct MisleadingIndentationChecker {
1344 unsigned NumDirectives;
1345 MisleadingStatementKind
Kind;
1347 MisleadingIndentationChecker(
Parser &
P, MisleadingStatementKind K,
1349 :
P(
P), StmtLoc(SL), PrevLoc(
P.getCurToken().getLocation()),
1350 NumDirectives(
P.getPreprocessor().getNumDirectives()),
Kind(K),
1351 ShouldSkip(
P.getCurToken().is(tok::l_brace)) {
1352 if (!
P.MisleadingIndentationElseLoc.isInvalid()) {
1353 StmtLoc =
P.MisleadingIndentationElseLoc;
1356 if (Kind == MSK_else && !ShouldSkip)
1357 P.MisleadingIndentationElseLoc = SL;
1363 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1365 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1366 if (ColNo == 0 || TabStop == 1)
1369 std::pair<FileID, unsigned> FIDAndOffset =
SM.getDecomposedLoc(Loc);
1372 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1376 const char *EndPos = BufData.data() + FIDAndOffset.second;
1378 assert(FIDAndOffset.second + 1 >= ColNo &&
1379 "Column number smaller than file offset?");
1381 unsigned VisualColumn = 0;
1384 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1386 if (*CurPos ==
'\t')
1388 VisualColumn += (TabStop - VisualColumn % TabStop);
1392 return VisualColumn + 1;
1396 Token Tok =
P.getCurToken();
1397 if (
P.getActions().getDiagnostics().isIgnored(
1398 diag::warn_misleading_indentation, Tok.
getLocation()) ||
1399 ShouldSkip || NumDirectives !=
P.getPreprocessor().getNumDirectives() ||
1403 (Kind == MSK_else &&
P.MisleadingIndentationElseLoc.isInvalid())) {
1407 if (Kind == MSK_else)
1411 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1412 unsigned CurColNum = getVisualIndentation(
SM, Tok.
getLocation());
1413 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1415 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1416 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1418 SM.getPresumedLineNumber(StmtLoc) !=
1420 (Tok.
isNot(tok::identifier) ||
1421 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1423 P.Diag(StmtLoc, diag::note_previous_statement);
1440 assert(Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1443 bool IsConstexpr =
false;
1444 bool IsConsteval =
false;
1448 if (Tok.
is(tok::kw_constexpr)) {
1450 : diag::ext_constexpr_if);
1454 if (Tok.
is(tok::exclaim)) {
1458 if (Tok.
is(tok::kw_consteval)) {
1460 : diag::ext_consteval_if);
1465 if (!IsConsteval && (NotLocation.
isValid() || Tok.
isNot(tok::l_paren))) {
1466 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1492 std::optional<bool> ConstexprCondition;
1495 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1505 bool IsBracedThen = Tok.
is(tok::l_brace);
1527 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1535 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1538 if (NotLocation.
isInvalid() && IsConsteval) {
1544 Actions, Context,
nullptr,
1546 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1549 if (Tok.
isNot(tok::kw_else))
1560 if (Tok.
is(tok::kw_else)) {
1561 if (TrailingElseLoc)
1577 Tok.
is(tok::l_brace));
1579 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1580 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1583 if (NotLocation.
isValid() && IsConsteval) {
1589 Actions, Context,
nullptr,
1591 ElseStmt = ParseStatement();
1598 }
else if (Tok.
is(tok::code_completion)) {
1602 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1603 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1619 auto IsCompoundStatement = [](
const Stmt *S) {
1620 if (
const auto *Outer = dyn_cast_or_null<AttributedStmt>(S))
1621 S = Outer->getSubStmt();
1622 return isa_and_nonnull<clang::CompoundStmt>(S);
1625 if (!IsCompoundStatement(ThenStmt.
get())) {
1626 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1630 if (!ElseStmt.
isUnset() && !IsCompoundStatement(ElseStmt.
get())) {
1631 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1646 else if (IsConsteval)
1650 return Actions.
ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.
get(), Cond, RParen,
1651 ThenStmt.
get(), ElseLoc, ElseStmt.
get());
1659 assert(Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1662 if (Tok.
isNot(tok::l_paren)) {
1663 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1685 ParseScope SwitchScope(
this, ScopeFlags);
1692 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1697 SwitchLoc, LParen, InitStmt.
get(), Cond, RParen);
1699 if (
Switch.isInvalid()) {
1704 if (Tok.
is(tok::l_brace)) {
1732 StmtResult Body(ParseStatement(TrailingElseLoc));
1746 assert(Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1750 if (Tok.
isNot(tok::l_paren)) {
1751 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1770 unsigned ScopeFlags;
1776 ParseScope WhileScope(
this, ScopeFlags);
1782 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1799 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1802 StmtResult Body(ParseStatement(TrailingElseLoc));
1804 if (Body.isUsable())
1810 if (Cond.
isInvalid() || Body.isInvalid())
1813 return Actions.
ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1821 assert(Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1826 unsigned ScopeFlags;
1832 ParseScope DoScope(
this, ScopeFlags);
1851 if (Tok.
isNot(tok::kw_while)) {
1852 if (!Body.isInvalid()) {
1853 Diag(Tok, diag::err_expected_while);
1854 Diag(DoLoc, diag::note_matching) <<
"'do'";
1861 if (Tok.
isNot(tok::l_paren)) {
1862 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1872 DiagnoseAndSkipCXX11Attributes();
1880 if (!Tok.
isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1883 Start, Start == Tok.
getLocation() ? Start : PrevTokLocation, {},
1889 if (Cond.
isInvalid() || Body.isInvalid())
1892 return Actions.
ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
1893 Cond.
get(), T.getCloseLocation());
1896bool Parser::isForRangeIdentifier() {
1897 assert(Tok.
is(tok::identifier));
1900 if (Next.is(tok::colon))
1903 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1904 TentativeParsingAction PA(*
this);
1906 SkipCXX11Attributes();
1939 assert(Tok.
is(tok::kw_for) &&
"Not a for stmt!");
1943 if (Tok.
is(tok::kw_co_await))
1946 if (Tok.
isNot(tok::l_paren)) {
1947 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1970 unsigned ScopeFlags = 0;
1974 ParseScope ForScope(
this, ScopeFlags);
1981 bool ForEach =
false;
1985 ForRangeInfo ForRangeInfo;
1988 if (Tok.
is(tok::code_completion)) {
1997 MaybeParseCXX11Attributes(attrs);
2002 if (Tok.
is(tok::semi)) {
2003 ProhibitAttributes(attrs);
2007 EmptyInitStmtSemiLoc = SemiLoc;
2010 isForRangeIdentifier()) {
2011 ProhibitAttributes(attrs);
2014 MaybeParseCXX11Attributes(attrs);
2017 if (Tok.
is(tok::l_brace))
2018 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2022 Diag(Loc, diag::err_for_range_identifier)
2027 ForRangeInfo.LoopVar =
2029 }
else if (isForInitDeclaration()) {
2033 if (!C99orCXXorObjC) {
2034 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2035 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2038 if (Tok.
is(tok::kw_using)) {
2043 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
2048 DG = ParseSimpleDeclaration(
2050 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2052 if (ForRangeInfo.ParsedForRangeDecl()) {
2054 ? diag::warn_cxx98_compat_for_range
2055 : diag::ext_for_range);
2056 ForRangeInfo.LoopVar = FirstPart;
2058 }
else if (Tok.
is(tok::semi)) {
2060 }
else if ((ForEach = isTokIdentifier_in())) {
2065 if (Tok.
is(tok::code_completion)) {
2072 Diag(Tok, diag::err_expected_semi_for);
2076 ProhibitAttributes(attrs);
2079 ForEach = isTokIdentifier_in();
2082 if (!
Value.isInvalid()) {
2091 bool IsRangeBasedFor =
2092 getLangOpts().CPlusPlus11 && !ForEach && Tok.
is(tok::colon);
2097 if (Tok.
is(tok::semi)) {
2099 }
else if (ForEach) {
2102 if (Tok.
is(tok::code_completion)) {
2111 Diag(Tok, diag::err_for_range_expected_decl)
2116 if (!
Value.isInvalid()) {
2117 Diag(Tok, diag::err_expected_semi_for);
2121 if (Tok.
is(tok::semi))
2128 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2131 if (Tok.
is(tok::semi)) {
2133 }
else if (Tok.
is(tok::r_paren)) {
2139 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2141 SecondPart = ParseCXXCondition(
2144 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2147 if (ForRangeInfo.ParsedForRangeDecl()) {
2149 : ForRangeInfo.ColonLoc,
2151 ? diag::warn_cxx17_compat_for_range_init_stmt
2152 : diag::ext_for_range_init_stmt)
2155 if (EmptyInitStmtSemiLoc.
isValid()) {
2156 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2182 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2183 if (Tok.
isNot(tok::semi)) {
2185 Diag(Tok, diag::err_expected_semi_for);
2191 if (Tok.
is(tok::semi)) {
2195 if (Tok.
isNot(tok::r_paren)) {
2207 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2208 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2213 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2221 if (ForRangeInfo.ParsedForRangeDecl()) {
2226 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
2231 }
else if (ForEach) {
2235 T.getCloseLocation());
2256 Tok.
is(tok::l_brace));
2265 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2268 StmtResult Body(ParseStatement(TrailingElseLoc));
2270 if (Body.isUsable())
2279 if (Body.isInvalid())
2286 if (ForRangeInfo.ParsedForRangeDecl())
2289 return Actions.
ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.
get(),
2290 SecondPart, ThirdPart, T.getCloseLocation(),
2302 assert(Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
2306 if (Tok.
is(tok::identifier)) {
2311 }
else if (Tok.
is(tok::star)) {
2313 Diag(Tok, diag::ext_gnu_indirect_goto);
2322 Diag(Tok, diag::err_expected) << tok::identifier;
2358 assert((Tok.
is(tok::kw_return) || Tok.
is(tok::kw_co_return)) &&
2359 "Not a return stmt!");
2360 bool IsCoreturn = Tok.
is(tok::kw_co_return);
2364 if (Tok.
isNot(tok::semi)) {
2368 if (Tok.
is(tok::code_completion) && !IsCoreturn) {
2376 R = ParseInitializer();
2380 ? diag::warn_cxx98_compat_generalized_initializer_lists
2381 : diag::ext_generalized_initializer_lists)
2395StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2396 ParsedStmtContext StmtCtx,
2405 while (Tok.
is(tok::annot_pragma_loop_hint)) {
2407 if (!HandlePragmaLoopHint(Hint))
2418 MaybeParseCXX11Attributes(Attrs);
2421 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2422 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);
2434Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2435 assert(Tok.
is(tok::l_brace));
2439 "parsing function body");
2445 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2450 StmtResult FnBody(ParseCompoundStatementBody());
2453 if (FnBody.isInvalid()) {
2468Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2469 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2473 "parsing function try block");
2476 if (Tok.
is(tok::colon))
2477 ParseConstructorInitializer(
Decl);
2485 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2488 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2491 if (FnBody.isInvalid()) {
2501bool Parser::trySkippingFunctionBody() {
2502 assert(SkipFunctionBodies &&
2503 "Should only be called when SkipFunctionBodies is enabled");
2511 TentativeParsingAction PA(*
this);
2512 bool IsTryCatch = Tok.
is(tok::kw_try);
2514 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2515 if (llvm::any_of(Toks, [](
const Token &Tok) {
2516 return Tok.
is(tok::code_completion);
2521 if (ErrorInPrologue) {
2530 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2547 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2550 return ParseCXXTryBlockCommon(TryLoc);
2570 if (Tok.
isNot(tok::l_brace))
2571 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2577 if (TryBlock.isInvalid())
2582 if ((Tok.
is(tok::identifier) &&
2584 Tok.
is(tok::kw___finally)) {
2589 Handler = ParseSEHExceptBlock(Loc);
2593 Handler = ParseSEHFinallyBlock(Loc);
2608 DiagnoseAndSkipCXX11Attributes();
2610 if (Tok.
isNot(tok::kw_catch))
2612 while (Tok.
is(tok::kw_catch)) {
2613 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2615 Handlers.push_back(Handler.
get());
2619 if (Handlers.empty())
2636StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2637 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2642 if (T.expectAndConsume())
2654 Decl *ExceptionDecl =
nullptr;
2655 if (Tok.
isNot(tok::ellipsis)) {
2657 MaybeParseCXX11Attributes(Attributes);
2661 if (ParseCXXTypeSpecifierSeq(DS))
2665 ParseDeclarator(ExDecl);
2671 if (T.getCloseLocation().isInvalid())
2674 if (Tok.
isNot(tok::l_brace))
2675 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2679 if (
Block.isInvalid())
2685void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2686 IfExistsCondition
Result;
2687 if (ParseMicrosoftIfExistsCondition(
Result))
2694 if (
Result.Behavior == IEB_Dependent) {
2695 if (!Tok.
is(tok::l_brace)) {
2696 Diag(Tok, diag::err_expected) << tok::l_brace;
2700 StmtResult Compound = ParseCompoundStatement();
2710 Stmts.push_back(DepResult.
get());
2715 if (Braces.consumeOpen()) {
2716 Diag(Tok, diag::err_expected) << tok::l_brace;
2720 switch (
Result.Behavior) {
2726 llvm_unreachable(
"Dependent case handled above");
2734 while (Tok.
isNot(tok::r_brace)) {
2736 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2738 Stmts.push_back(R.
get());
2740 Braces.consumeClose();
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Defines the clang::TokenKind enum and support functions.
Attr - This represents one attribute.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
Captures information about "declaration specifiers".
Decl - This represents one declaration (or definition), e.g.
Information about one declarator, including the parsed type information and the identifier.
RAII object that enters a new expression evaluation context.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
Represents a member of a struct/union/class.
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.
One of these records is kept for each identifier that is lexed.
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
StringRef getName() const
Return the actual identifier string.
Represents the declaration of a label.
@ FEM_Source
Use the declared type for fp arithmetic.
Represent a C++ namespace.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
ParsedAttributes - A collection of parsed attributes.
void takeAllFrom(ParsedAttributes &Other)
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Sema::FullExprArg FullExprArg
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
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
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
SmallVector< Stmt *, 32 > StmtVector
A SmallVector of statements.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
An RAII object for [un]poisoning an identifier within a scope.
void enterReturn(Sema &S, SourceLocation Tok)
QualType get(SourceLocation Tok) const
Get the expected type associated with this location, if any.
SourceLocation getLastFPEvalPragmaLocation() const
LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const
SourceManager & getSourceManager() const
const TargetInfo & getTargetInfo() const
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
If a crash happens while one of these objects are live, the message is printed out along with the spe...
void AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
void decrementMSManglingNumber()
@ SEHTryScope
This scope corresponds to an SEH try.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
@ CatchScope
This is the scope of a C++ catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ FnTryCatchScope
This is the scope for a function-level C++ try or catch scope.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ TryScope
This is the scope of a C++ try statement.
@ DeclScope
This is a scope that can contain a declaration.
A RAII object to enter scope of a compound statement.
std::optional< bool > getKnownValue() const
Records and restores the CurFPFeatures state on entry/exit of compound statements.
StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, IdentifierInfo *Ident, ParsedAttributes &Attrs)
void CodeCompleteCase(Scope *S)
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult ActOnForEachLValueExpr(Expr *E)
In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
bool CheckCaseExpression(Expr *E)
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen)
ASTContext & getASTContext() const
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data)
Perform code-completion in an expression context when we know what type we're looking for.
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
StmtResult ActOnExprStmtError()
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
Decl * ActOnExceptionDeclarator(Scope *S, Declarator &D)
ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch handler.
LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())
LookupOrCreateLabel - Do a name lookup of a label with the specified name.
Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope)
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind)
ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
ExpressionEvaluationContext
Describes how the expressions currently being parsed are evaluated at run-time, if at all.
@ DiscardedStatement
The current expression occurs within a discarded statement.
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
void ActOnAfterCompoundStatementLeadingPragmas()
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope)
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
void ActOnStartSEHFinallyBlock()
void ActOnAbortSEHFinallyBlock()
@ BFRK_Build
Initial building of a for-range statement.
StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)
ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
ExprResult ActOnStmtExprResult(ExprResult E)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
QualType PreferredConditionType(ConditionKind K) const
void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar)
static ConditionResult ConditionError()
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
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.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
virtual bool supportSourceEvalMethod() const
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
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
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingEmptyMacro() const
Return true if this token has an empty macro before it.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
NestedNameSpecifier * getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
Represents a variable declaration or definition.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
@ Result
The result type of a method or function.
ActionResult< Stmt * > StmtResult
Loop optimization hint for loop and unroll pragmas.
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc