27#include "llvm/ADT/STLExtras.h"
39 ParsedStmtContext StmtCtx) {
46 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
102Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
103 ParsedStmtContext StmtCtx,
114 MaybeParseCXX11Attributes(CXX11Attrs,
true);
117 MaybeParseGNUAttributes(GNUAttrs);
119 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
120 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUAttrs);
121 MaybeDestroyTemplateIds();
129 "attributes on empty statement");
140 StatementFilterCCC(
Token nextTok) : NextToken(nextTok) {
141 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
142 tok::identifier, tok::star, tok::amp);
143 WantExpressionKeywords =
144 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
145 WantRemainingKeywords =
146 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
147 WantCXXNamedCasts =
false;
150 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
153 if (NextToken.is(tok::equal))
155 if (NextToken.is(tok::period) &&
161 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
162 return std::make_unique<StatementFilterCCC>(*
this);
170StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
171 StmtVector &Stmts, ParsedStmtContext StmtCtx,
174 const char *SemiError =
nullptr;
188 return ParseObjCAtStatement(AtLoc, StmtCtx);
191 case tok::code_completion:
196 case tok::identifier:
199 if (Next.is(tok::colon)) {
207 return ParseLabeledStatement(Attrs, StmtCtx);
212 if (Next.isNot(tok::coloncolon)) {
215 StatementFilterCCC CCC(Next);
216 if (TryAnnotateName(&CCC) == ANK_Error) {
220 if (Tok.
is(tok::semi))
226 if (Tok.
isNot(tok::identifier))
235 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
237 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
238 llvm::all_of(GNUAttrs, IsStmtAttr);
239 if (((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";
339 (AL.isRegularKeywordAttribute()
340 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
341 :
Diag(AL.
getRange().getBegin(), diag::warn_attribute_ignored))
345 ProhibitAttributes(GNUAttrs);
347 Res = ParseAsmStatement(msAsm);
348 if (msAsm)
return Res;
353 case tok::kw___if_exists:
354 case tok::kw___if_not_exists:
355 ProhibitAttributes(CXX11Attrs);
356 ProhibitAttributes(GNUAttrs);
357 ParseMicrosoftIfExistsStatement(Stmts);
363 return ParseCXXTryBlock();
366 ProhibitAttributes(CXX11Attrs);
367 ProhibitAttributes(GNUAttrs);
368 return ParseSEHTryBlock();
370 case tok::kw___leave:
371 Res = ParseSEHLeaveStatement();
372 SemiError =
"__leave";
375 case tok::annot_pragma_vis:
376 ProhibitAttributes(CXX11Attrs);
377 ProhibitAttributes(GNUAttrs);
378 HandlePragmaVisibility();
381 case tok::annot_pragma_pack:
382 ProhibitAttributes(CXX11Attrs);
383 ProhibitAttributes(GNUAttrs);
387 case tok::annot_pragma_msstruct:
388 ProhibitAttributes(CXX11Attrs);
389 ProhibitAttributes(GNUAttrs);
390 HandlePragmaMSStruct();
393 case tok::annot_pragma_align:
394 ProhibitAttributes(CXX11Attrs);
395 ProhibitAttributes(GNUAttrs);
399 case tok::annot_pragma_weak:
400 ProhibitAttributes(CXX11Attrs);
401 ProhibitAttributes(GNUAttrs);
405 case tok::annot_pragma_weakalias:
406 ProhibitAttributes(CXX11Attrs);
407 ProhibitAttributes(GNUAttrs);
408 HandlePragmaWeakAlias();
411 case tok::annot_pragma_redefine_extname:
412 ProhibitAttributes(CXX11Attrs);
413 ProhibitAttributes(GNUAttrs);
414 HandlePragmaRedefineExtname();
417 case tok::annot_pragma_fp_contract:
418 ProhibitAttributes(CXX11Attrs);
419 ProhibitAttributes(GNUAttrs);
420 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
421 ConsumeAnnotationToken();
424 case tok::annot_pragma_fp:
425 ProhibitAttributes(CXX11Attrs);
426 ProhibitAttributes(GNUAttrs);
427 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
428 ConsumeAnnotationToken();
431 case tok::annot_pragma_fenv_access:
432 case tok::annot_pragma_fenv_access_ms:
433 ProhibitAttributes(CXX11Attrs);
434 ProhibitAttributes(GNUAttrs);
435 Diag(Tok, diag::err_pragma_file_or_compound_scope)
436 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
438 ConsumeAnnotationToken();
441 case tok::annot_pragma_fenv_round:
442 ProhibitAttributes(CXX11Attrs);
443 ProhibitAttributes(GNUAttrs);
444 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
445 ConsumeAnnotationToken();
448 case tok::annot_pragma_cx_limited_range:
449 ProhibitAttributes(CXX11Attrs);
450 ProhibitAttributes(GNUAttrs);
451 Diag(Tok, diag::err_pragma_file_or_compound_scope)
452 <<
"STDC CX_LIMITED_RANGE";
453 ConsumeAnnotationToken();
456 case tok::annot_pragma_float_control:
457 ProhibitAttributes(CXX11Attrs);
458 ProhibitAttributes(GNUAttrs);
459 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
460 ConsumeAnnotationToken();
463 case tok::annot_pragma_opencl_extension:
464 ProhibitAttributes(CXX11Attrs);
465 ProhibitAttributes(GNUAttrs);
466 HandlePragmaOpenCLExtension();
469 case tok::annot_pragma_captured:
470 ProhibitAttributes(CXX11Attrs);
471 ProhibitAttributes(GNUAttrs);
472 return HandlePragmaCaptured();
474 case tok::annot_pragma_openmp:
477 ProhibitAttributes(CXX11Attrs);
478 ProhibitAttributes(GNUAttrs);
480 case tok::annot_attr_openmp:
482 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
484 case tok::annot_pragma_openacc:
487 case tok::annot_pragma_ms_pointers_to_members:
488 ProhibitAttributes(CXX11Attrs);
489 ProhibitAttributes(GNUAttrs);
490 HandlePragmaMSPointersToMembers();
493 case tok::annot_pragma_ms_pragma:
494 ProhibitAttributes(CXX11Attrs);
495 ProhibitAttributes(GNUAttrs);
496 HandlePragmaMSPragma();
499 case tok::annot_pragma_ms_vtordisp:
500 ProhibitAttributes(CXX11Attrs);
501 ProhibitAttributes(GNUAttrs);
502 HandlePragmaMSVtorDisp();
505 case tok::annot_pragma_loop_hint:
506 ProhibitAttributes(CXX11Attrs);
507 ProhibitAttributes(GNUAttrs);
508 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);
510 case tok::annot_pragma_dump:
514 case tok::annot_pragma_attribute:
515 HandlePragmaAttribute();
524 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
533StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
535 Token OldToken = Tok;
541 if (
Expr.isInvalid()) {
546 if (Tok.
is(tok::semi))
555 Diag(OldToken, diag::err_expected_case_before_expression)
559 return ParseCaseStatement(StmtCtx,
true,
Expr);
562 Token *CurTok =
nullptr;
567 if (Tok.
is(tok::annot_repl_input_end) && Actions.
getLangOpts().CPlusPlus)
571 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
590 assert(Tok.
is(tok::kw___try) &&
"Expected '__try'");
593 if (Tok.
isNot(tok::l_brace))
594 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
599 if (TryBlock.isInvalid())
603 if (Tok.
is(tok::identifier) &&
606 Handler = ParseSEHExceptBlock(Loc);
607 }
else if (Tok.
is(tok::kw___finally)) {
609 Handler = ParseSEHFinallyBlock(Loc);
630 raii2(Ident___exception_code,
false),
631 raii3(Ident_GetExceptionCode,
false);
633 if (ExpectAndConsume(tok::l_paren))
647 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
661 if (ExpectAndConsume(tok::r_paren))
664 if (Tok.
isNot(tok::l_brace))
665 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
669 if(
Block.isInvalid())
682 raii2(Ident___abnormal_termination,
false),
683 raii3(Ident_AbnormalTermination,
false);
685 if (Tok.
isNot(tok::l_brace))
686 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
688 ParseScope FinallyScope(
this, 0);
692 if(
Block.isInvalid()) {
713 if (!
P.getLangOpts().CPlusPlus && !
P.getLangOpts().MicrosoftExt &&
714 isa<DeclStmt>(SubStmt)) {
717 ? diag::warn_c23_compat_label_followed_by_declaration
718 : diag::ext_c_label_followed_by_declaration);
732 ParsedStmtContext StmtCtx) {
734 "Not an identifier!");
739 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
741 Token IdentTok = Tok;
744 assert(Tok.
is(tok::colon) &&
"Not a label!");
751 if (Tok.
is(tok::kw___attribute)) {
753 ParseGNUAttributes(TempAttrs);
767 SubStmt = ParseStatementOrDeclarationAfterAttributes(
768 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs, TempAttrs);
769 if (!TempAttrs.empty() && !SubStmt.
isInvalid())
775 if (SubStmt.
isUnset() && Tok.
is(tok::r_brace)) {
776 DiagnoseLabelAtEndOfCompoundStatement();
782 SubStmt = ParseStatement(
nullptr, StmtCtx);
804StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
806 assert((MissingCase || Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
811 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
834 Stmt *DeepestParsedCaseStmt =
nullptr;
843 if (Tok.
is(tok::code_completion)) {
872 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
880 ColonProtection.restore();
886 Diag(ColonLoc, diag::err_expected_after)
887 <<
"'case'" << tok::colon
891 Diag(ExpectedLoc, diag::err_expected_after)
892 <<
"'case'" << tok::colon
894 ColonLoc = ExpectedLoc;
898 Actions.
ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
903 if (TopLevelCase.isInvalid())
904 return ParseStatement(
nullptr, StmtCtx);
909 Stmt *NextDeepest = Case.
get();
910 if (TopLevelCase.isInvalid())
914 DeepestParsedCaseStmt = NextDeepest;
918 }
while (Tok.
is(tok::kw_case));
923 if (Tok.
is(tok::r_brace)) {
926 DiagnoseLabelAtEndOfCompoundStatement();
929 SubStmt = ParseStatement(
nullptr, StmtCtx);
933 if (DeepestParsedCaseStmt) {
950StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
951 assert(Tok.
is(tok::kw_default) &&
"Not a default stmt!");
956 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
964 Diag(ColonLoc, diag::err_expected_after)
965 <<
"'default'" << tok::colon
969 Diag(ExpectedLoc, diag::err_expected_after)
970 <<
"'default'" << tok::colon
972 ColonLoc = ExpectedLoc;
977 if (Tok.
is(tok::r_brace)) {
980 DiagnoseLabelAtEndOfCompoundStatement();
983 SubStmt = ParseStatement(
nullptr, StmtCtx);
995StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
996 return ParseCompoundStatement(isStmtExpr,
1022StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
1023 unsigned ScopeFlags) {
1024 assert(Tok.
is(tok::l_brace) &&
"Not a compound stmt!");
1028 ParseScope CompoundScope(
this, ScopeFlags);
1031 return ParseCompoundStatementBody(isStmtExpr);
1037void Parser::ParseCompoundStatementLeadingPragmas() {
1038 bool checkForPragmas =
true;
1039 while (checkForPragmas) {
1041 case tok::annot_pragma_vis:
1042 HandlePragmaVisibility();
1044 case tok::annot_pragma_pack:
1047 case tok::annot_pragma_msstruct:
1048 HandlePragmaMSStruct();
1050 case tok::annot_pragma_align:
1051 HandlePragmaAlign();
1053 case tok::annot_pragma_weak:
1056 case tok::annot_pragma_weakalias:
1057 HandlePragmaWeakAlias();
1059 case tok::annot_pragma_redefine_extname:
1060 HandlePragmaRedefineExtname();
1062 case tok::annot_pragma_opencl_extension:
1063 HandlePragmaOpenCLExtension();
1065 case tok::annot_pragma_fp_contract:
1066 HandlePragmaFPContract();
1068 case tok::annot_pragma_fp:
1071 case tok::annot_pragma_fenv_access:
1072 case tok::annot_pragma_fenv_access_ms:
1073 HandlePragmaFEnvAccess();
1075 case tok::annot_pragma_fenv_round:
1076 HandlePragmaFEnvRound();
1078 case tok::annot_pragma_cx_limited_range:
1079 HandlePragmaCXLimitedRange();
1081 case tok::annot_pragma_float_control:
1082 HandlePragmaFloatControl();
1084 case tok::annot_pragma_ms_pointers_to_members:
1085 HandlePragmaMSPointersToMembers();
1087 case tok::annot_pragma_ms_pragma:
1088 HandlePragmaMSPragma();
1090 case tok::annot_pragma_ms_vtordisp:
1091 HandlePragmaMSVtorDisp();
1093 case tok::annot_pragma_dump:
1097 checkForPragmas =
false;
1104void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1107 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1108 : diag::ext_cxx_label_end_of_compound_statement);
1111 ? diag::warn_c23_compat_label_end_of_compound_statement
1112 : diag::ext_c_label_end_of_compound_statement);
1118bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1119 if (!Tok.
is(tok::semi))
1131 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1133 Stmts.push_back(R.
get());
1140 Diag(StartLoc, diag::warn_null_statement)
1146 bool IsStmtExprResult =
false;
1147 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1149 unsigned LookAhead = 0;
1150 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
1156 IsStmtExprResult = GetLookAheadToken(LookAhead).
is(tok::r_brace) &&
1157 GetLookAheadToken(LookAhead + 1).
is(tok::r_paren);
1160 if (IsStmtExprResult)
1169StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1172 "in compound statement ('{}')");
1180 if (
T.consumeOpen())
1186 ParseCompoundStatementLeadingPragmas();
1193 while (Tok.
is(tok::kw___label__)) {
1198 if (Tok.
isNot(tok::identifier)) {
1199 Diag(Tok, diag::err_expected) << tok::identifier;
1216 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1218 Stmts.push_back(R.
get());
1221 ParsedStmtContext SubStmtCtx =
1222 ParsedStmtContext::Compound |
1223 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1225 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
1226 Tok.
isNot(tok::eof)) {
1227 if (Tok.
is(tok::annot_pragma_unused)) {
1228 HandlePragmaUnused();
1232 if (ConsumeNullStmt(Stmts))
1236 if (Tok.
isNot(tok::kw___extension__)) {
1237 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1244 while (Tok.
is(tok::kw___extension__))
1248 MaybeParseCXX11Attributes(attrs,
true);
1251 if (isDeclarationStatement()) {
1259 attrs, DeclSpecAttrs);
1263 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1265 if (Res.isInvalid()) {
1272 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1273 R = handleExprStmt(Res, SubStmtCtx);
1280 Stmts.push_back(R.
get());
1291 diag::warn_no_support_for_eval_method_source_on_m32);
1296 if (!
T.consumeClose()) {
1299 if (isStmtExpr && Tok.
is(tok::r_paren))
1300 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1306 if (
T.getCloseLocation().isValid())
1307 CloseLoc =
T.getCloseLocation();
1327bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1338 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1357 if (Tok.
isNot(tok::r_paren))
1363 Start, Tok.
getLocation() == Start ? Start : PrevTokLocation, {},
1372 LParenLoc =
T.getOpenLocation();
1373 RParenLoc =
T.getCloseLocation();
1378 while (Tok.
is(tok::r_paren)) {
1379 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1389enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1391struct MisleadingIndentationChecker {
1395 unsigned NumDirectives;
1396 MisleadingStatementKind
Kind;
1398 MisleadingIndentationChecker(
Parser &
P, MisleadingStatementKind K,
1400 :
P(
P), StmtLoc(SL), PrevLoc(
P.getCurToken().getLocation()),
1401 NumDirectives(
P.getPreprocessor().getNumDirectives()),
Kind(K),
1402 ShouldSkip(
P.getCurToken().is(tok::l_brace)) {
1403 if (!
P.MisleadingIndentationElseLoc.isInvalid()) {
1404 StmtLoc =
P.MisleadingIndentationElseLoc;
1407 if (Kind == MSK_else && !ShouldSkip)
1408 P.MisleadingIndentationElseLoc = SL;
1414 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1416 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1417 if (ColNo == 0 || TabStop == 1)
1420 std::pair<FileID, unsigned> FIDAndOffset =
SM.getDecomposedLoc(Loc);
1423 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1427 const char *EndPos = BufData.data() + FIDAndOffset.second;
1429 assert(FIDAndOffset.second + 1 >= ColNo &&
1430 "Column number smaller than file offset?");
1432 unsigned VisualColumn = 0;
1435 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1437 if (*CurPos ==
'\t')
1439 VisualColumn += (TabStop - VisualColumn % TabStop);
1443 return VisualColumn + 1;
1447 Token Tok =
P.getCurToken();
1448 if (
P.getActions().getDiagnostics().isIgnored(
1449 diag::warn_misleading_indentation, Tok.
getLocation()) ||
1450 ShouldSkip || NumDirectives !=
P.getPreprocessor().getNumDirectives() ||
1454 (Kind == MSK_else &&
P.MisleadingIndentationElseLoc.isInvalid())) {
1458 if (Kind == MSK_else)
1462 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1463 unsigned CurColNum = getVisualIndentation(
SM, Tok.
getLocation());
1464 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1466 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1467 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1469 SM.getPresumedLineNumber(StmtLoc) !=
1471 (Tok.
isNot(tok::identifier) ||
1472 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1474 P.Diag(StmtLoc, diag::note_previous_statement);
1491 assert(Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1494 bool IsConstexpr =
false;
1495 bool IsConsteval =
false;
1499 if (Tok.
is(tok::kw_constexpr)) {
1501 : diag::ext_constexpr_if);
1505 if (Tok.
is(tok::exclaim)) {
1509 if (Tok.
is(tok::kw_consteval)) {
1511 : diag::ext_consteval_if);
1516 if (!IsConsteval && (NotLocation.
isValid() || Tok.
isNot(tok::l_paren))) {
1517 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1543 std::optional<bool> ConstexprCondition;
1546 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1556 bool IsBracedThen = Tok.
is(tok::l_brace);
1578 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1586 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1589 if (NotLocation.
isInvalid() && IsConsteval) {
1595 Actions, Context,
nullptr,
1597 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1600 if (Tok.
isNot(tok::kw_else))
1611 if (Tok.
is(tok::kw_else)) {
1612 if (TrailingElseLoc)
1628 Tok.
is(tok::l_brace));
1630 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1631 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1634 if (NotLocation.
isValid() && IsConsteval) {
1640 Actions, Context,
nullptr,
1642 ElseStmt = ParseStatement();
1649 }
else if (Tok.
is(tok::code_completion)) {
1653 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1654 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1670 auto IsCompoundStatement = [](
const Stmt *S) {
1671 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1672 S = Outer->getSubStmt();
1673 return isa_and_nonnull<clang::CompoundStmt>(S);
1676 if (!IsCompoundStatement(ThenStmt.
get())) {
1677 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1681 if (!ElseStmt.
isUnset() && !IsCompoundStatement(ElseStmt.
get())) {
1682 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1697 else if (IsConsteval)
1701 return Actions.
ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.
get(), Cond, RParen,
1702 ThenStmt.
get(), ElseLoc, ElseStmt.
get());
1710 assert(Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1713 if (Tok.
isNot(tok::l_paren)) {
1714 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1736 ParseScope SwitchScope(
this, ScopeFlags);
1743 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1748 SwitchLoc, LParen, InitStmt.
get(), Cond, RParen);
1750 if (
Switch.isInvalid()) {
1755 if (Tok.
is(tok::l_brace)) {
1783 StmtResult Body(ParseStatement(TrailingElseLoc));
1797 assert(Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1801 if (Tok.
isNot(tok::l_paren)) {
1802 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1821 unsigned ScopeFlags;
1827 ParseScope WhileScope(
this, ScopeFlags);
1833 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1850 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1853 StmtResult Body(ParseStatement(TrailingElseLoc));
1855 if (Body.isUsable())
1861 if (Cond.
isInvalid() || Body.isInvalid())
1864 return Actions.
ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1872 assert(Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1877 unsigned ScopeFlags;
1883 ParseScope DoScope(
this, ScopeFlags);
1902 if (Tok.
isNot(tok::kw_while)) {
1903 if (!Body.isInvalid()) {
1904 Diag(Tok, diag::err_expected_while);
1905 Diag(DoLoc, diag::note_matching) <<
"'do'";
1912 if (Tok.
isNot(tok::l_paren)) {
1913 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1923 DiagnoseAndSkipCXX11Attributes();
1932 if (!Tok.
isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1935 Start, Start == Tok.
getLocation() ? Start : PrevTokLocation, {},
1941 if (Cond.
isInvalid() || Body.isInvalid())
1944 return Actions.
ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1945 Cond.
get(),
T.getCloseLocation());
1948bool Parser::isForRangeIdentifier() {
1949 assert(Tok.
is(tok::identifier));
1952 if (Next.is(tok::colon))
1955 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1956 TentativeParsingAction PA(*
this);
1958 SkipCXX11Attributes();
1991 assert(Tok.
is(tok::kw_for) &&
"Not a for stmt!");
1995 if (Tok.
is(tok::kw_co_await))
1998 if (Tok.
isNot(tok::l_paren)) {
1999 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
2022 unsigned ScopeFlags = 0;
2026 ParseScope ForScope(
this, ScopeFlags);
2033 bool ForEach =
false;
2037 ForRangeInfo ForRangeInfo;
2040 if (Tok.
is(tok::code_completion)) {
2049 MaybeParseCXX11Attributes(attrs);
2054 if (Tok.
is(tok::semi)) {
2055 ProhibitAttributes(attrs);
2059 EmptyInitStmtSemiLoc = SemiLoc;
2062 isForRangeIdentifier()) {
2063 ProhibitAttributes(attrs);
2066 MaybeParseCXX11Attributes(attrs);
2069 if (Tok.
is(tok::l_brace))
2070 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2074 Diag(Loc, diag::err_for_range_identifier)
2079 ForRangeInfo.LoopVar =
2081 }
else if (isForInitDeclaration()) {
2085 if (!C99orCXXorObjC) {
2086 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2087 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2091 if (Tok.
is(tok::kw_using)) {
2097 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
2100 DG = ParseSimpleDeclaration(
2102 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2104 if (ForRangeInfo.ParsedForRangeDecl()) {
2106 ? diag::warn_cxx98_compat_for_range
2107 : diag::ext_for_range);
2108 ForRangeInfo.LoopVar = FirstPart;
2110 }
else if (Tok.
is(tok::semi)) {
2112 }
else if ((ForEach = isTokIdentifier_in())) {
2117 if (Tok.
is(tok::code_completion)) {
2124 Diag(Tok, diag::err_expected_semi_for);
2128 ProhibitAttributes(attrs);
2131 ForEach = isTokIdentifier_in();
2134 if (!
Value.isInvalid()) {
2143 bool IsRangeBasedFor =
2144 getLangOpts().CPlusPlus11 && !ForEach && Tok.
is(tok::colon);
2149 if (Tok.
is(tok::semi)) {
2151 }
else if (ForEach) {
2154 if (Tok.
is(tok::code_completion)) {
2163 Diag(Tok, diag::err_for_range_expected_decl)
2168 if (!
Value.isInvalid()) {
2169 Diag(Tok, diag::err_expected_semi_for);
2173 if (Tok.
is(tok::semi))
2180 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2183 if (Tok.
is(tok::semi)) {
2185 }
else if (Tok.
is(tok::r_paren)) {
2191 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2195 SecondPart = ParseCXXCondition(
2196 nullptr, ForLoc, CK,
2198 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2201 if (ForRangeInfo.ParsedForRangeDecl()) {
2203 : ForRangeInfo.ColonLoc,
2205 ? diag::warn_cxx17_compat_for_range_init_stmt
2206 : diag::ext_for_range_init_stmt)
2209 if (EmptyInitStmtSemiLoc.
isValid()) {
2210 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2219 Tok.
getLocation() == SecondPartStart ? SecondPartStart
2249 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2250 if (Tok.
isNot(tok::semi)) {
2252 Diag(Tok, diag::err_expected_semi_for);
2256 if (Tok.
is(tok::semi)) {
2260 if (Tok.
isNot(tok::r_paren)) {
2272 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2273 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2278 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2286 if (ForRangeInfo.ParsedForRangeDecl()) {
2291 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
2293 ForRangeInfo.LifetimeExtendTemps);
2294 }
else if (ForEach) {
2300 T.getCloseLocation());
2321 Tok.
is(tok::l_brace));
2330 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2333 StmtResult Body(ParseStatement(TrailingElseLoc));
2335 if (Body.isUsable())
2344 if (Body.isInvalid())
2351 if (ForRangeInfo.ParsedForRangeDecl())
2355 SecondPart, ThirdPart,
T.getCloseLocation(),
2367 assert(Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
2371 if (Tok.
is(tok::identifier)) {
2376 }
else if (Tok.
is(tok::star)) {
2378 Diag(Tok, diag::ext_gnu_indirect_goto);
2387 Diag(Tok, diag::err_expected) << tok::identifier;
2423 assert((Tok.
is(tok::kw_return) || Tok.
is(tok::kw_co_return)) &&
2424 "Not a return stmt!");
2425 bool IsCoreturn = Tok.
is(tok::kw_co_return);
2429 if (Tok.
isNot(tok::semi)) {
2433 if (Tok.
is(tok::code_completion) && !IsCoreturn) {
2441 R = ParseInitializer();
2445 ? diag::warn_cxx98_compat_generalized_initializer_lists
2446 : diag::ext_generalized_initializer_lists)
2460StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2461 ParsedStmtContext StmtCtx,
2470 while (Tok.
is(tok::annot_pragma_loop_hint)) {
2472 if (!HandlePragmaLoopHint(Hint))
2479 ParsedAttr::Form::Pragma());
2483 MaybeParseCXX11Attributes(Attrs);
2486 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2487 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);
2499Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2500 assert(Tok.
is(tok::l_brace));
2504 "parsing function body");
2510 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2515 StmtResult FnBody(ParseCompoundStatementBody());
2518 if (FnBody.isInvalid()) {
2533Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2534 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2538 "parsing function try block");
2541 if (Tok.
is(tok::colon))
2542 ParseConstructorInitializer(
Decl);
2550 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2553 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2556 if (FnBody.isInvalid()) {
2566bool Parser::trySkippingFunctionBody() {
2567 assert(SkipFunctionBodies &&
2568 "Should only be called when SkipFunctionBodies is enabled");
2576 TentativeParsingAction PA(*
this);
2577 bool IsTryCatch = Tok.
is(tok::kw_try);
2579 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2580 if (llvm::any_of(Toks, [](
const Token &Tok) {
2581 return Tok.
is(tok::code_completion);
2586 if (ErrorInPrologue) {
2595 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2612 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2615 return ParseCXXTryBlockCommon(TryLoc);
2635 if (Tok.
isNot(tok::l_brace))
2636 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2642 if (TryBlock.isInvalid())
2647 if ((Tok.
is(tok::identifier) &&
2649 Tok.
is(tok::kw___finally)) {
2654 Handler = ParseSEHExceptBlock(Loc);
2658 Handler = ParseSEHFinallyBlock(Loc);
2673 DiagnoseAndSkipCXX11Attributes();
2675 if (Tok.
isNot(tok::kw_catch))
2677 while (Tok.
is(tok::kw_catch)) {
2678 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2680 Handlers.push_back(Handler.
get());
2684 if (Handlers.empty())
2701StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2702 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2707 if (
T.expectAndConsume())
2719 Decl *ExceptionDecl =
nullptr;
2720 if (Tok.
isNot(tok::ellipsis)) {
2722 MaybeParseCXX11Attributes(Attributes);
2726 if (ParseCXXTypeSpecifierSeq(DS))
2730 ParseDeclarator(ExDecl);
2736 if (
T.getCloseLocation().isInvalid())
2739 if (Tok.
isNot(tok::l_brace))
2740 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2744 if (
Block.isInvalid())
2750void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2751 IfExistsCondition
Result;
2752 if (ParseMicrosoftIfExistsCondition(
Result))
2759 if (
Result.Behavior == IEB_Dependent) {
2760 if (!Tok.
is(tok::l_brace)) {
2761 Diag(Tok, diag::err_expected) << tok::l_brace;
2765 StmtResult Compound = ParseCompoundStatement();
2775 Stmts.push_back(DepResult.
get());
2780 if (
Braces.consumeOpen()) {
2781 Diag(Tok, diag::err_expected) << tok::l_brace;
2785 switch (
Result.Behavior) {
2791 llvm_unreachable(
"Dependent case handled above");
2799 while (Tok.
isNot(tok::r_brace)) {
2801 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2803 Stmts.push_back(R.
get());
static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
This file declares semantic analysis for OpenMP constructs and clauses.
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
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)
StmtResult ParseOpenACCDirectiveStmt()
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.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
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)
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)
const LangOptions & getLangOpts() const
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)
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
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 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.
void setAnnotationValue(void *val)
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.
Defines the clang::TargetInfo interface.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
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
const FunctionProtoType * T
@ Braces
New-expression has a C++11 list-initializer.
Loop optimization hint for loop and unroll pragmas.
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc