29 #include "llvm/ADT/STLExtras.h"
32 using namespace clang;
41 ParsedStmtContext StmtCtx) {
48 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
49 }
while (!Res.isInvalid() && !Res.get());
104 Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
105 ParsedStmtContext StmtCtx,
116 MaybeParseCXX11Attributes(CXX11Attrs,
true);
119 MaybeParseGNUAttributes(GNUAttrs);
121 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
122 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUAttrs);
123 MaybeDestroyTemplateIds();
130 assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
131 "attributes on empty statement");
133 if (Attrs.empty() || Res.isInvalid())
142 StatementFilterCCC(
Token nextTok) : NextToken(nextTok) {
143 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
144 tok::identifier, tok::star, tok::amp);
145 WantExpressionKeywords =
146 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
147 WantRemainingKeywords =
148 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
149 WantCXXNamedCasts =
false;
152 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
155 if (NextToken.is(tok::equal))
157 if (NextToken.is(tok::period) &&
163 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
164 return std::make_unique<StatementFilterCCC>(*
this);
172 StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
173 StmtVector &Stmts, ParsedStmtContext StmtCtx,
176 const char *SemiError =
nullptr;
190 return ParseObjCAtStatement(AtLoc, StmtCtx);
193 case tok::code_completion:
199 case tok::identifier:
202 if (Next.is(tok::colon)) {
210 return ParseLabeledStatement(Attrs, StmtCtx);
215 if (Next.isNot(tok::coloncolon)) {
218 StatementFilterCCC CCC(Next);
219 if (TryAnnotateName(&CCC) == ANK_Error) {
223 if (Tok.
is(tok::semi))
229 if (Tok.
isNot(tok::identifier))
238 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
240 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
241 llvm::all_of(GNUAttrs, IsStmtAttr);
242 if (((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
243 isDeclarationStatement())) {
246 if (GNUAttributeLoc.
isValid()) {
247 DeclStart = GNUAttributeLoc;
249 GNUAttrs, &GNUAttributeLoc);
265 if (Tok.
is(tok::r_brace)) {
266 Diag(Tok, diag::err_expected_statement);
271 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
272 #include "clang/Basic/TransformTypeTraits.def"
275 Diag(Tok, diag::ext_keyword_as_ident)
277 goto ParseIdentifier;
281 return ParseExprStatement(StmtCtx);
285 case tok::kw___attribute: {
287 ParseGNUAttributes(GNUAttrs);
292 return ParseCaseStatement(StmtCtx);
293 case tok::kw_default:
294 return ParseDefaultStatement(StmtCtx);
297 return ParseCompoundStatement();
304 return ParseIfStatement(TrailingElseLoc);
306 return ParseSwitchStatement(TrailingElseLoc);
309 return ParseWhileStatement(TrailingElseLoc);
311 Res = ParseDoStatement();
312 SemiError =
"do/while";
315 return ParseForStatement(TrailingElseLoc);
318 Res = ParseGotoStatement();
321 case tok::kw_continue:
322 Res = ParseContinueStatement();
323 SemiError =
"continue";
326 Res = ParseBreakStatement();
330 Res = ParseReturnStatement();
331 SemiError =
"return";
333 case tok::kw_co_return:
334 Res = ParseReturnStatement();
335 SemiError =
"co_return";
342 (AL.isRegularKeywordAttribute()
343 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
344 :
Diag(AL.
getRange().getBegin(), diag::warn_attribute_ignored))
348 ProhibitAttributes(GNUAttrs);
350 Res = ParseAsmStatement(msAsm);
351 if (msAsm)
return Res;
356 case tok::kw___if_exists:
357 case tok::kw___if_not_exists:
358 ProhibitAttributes(CXX11Attrs);
359 ProhibitAttributes(GNUAttrs);
360 ParseMicrosoftIfExistsStatement(Stmts);
366 return ParseCXXTryBlock();
369 ProhibitAttributes(CXX11Attrs);
370 ProhibitAttributes(GNUAttrs);
371 return ParseSEHTryBlock();
373 case tok::kw___leave:
374 Res = ParseSEHLeaveStatement();
375 SemiError =
"__leave";
378 case tok::annot_pragma_vis:
379 ProhibitAttributes(CXX11Attrs);
380 ProhibitAttributes(GNUAttrs);
381 HandlePragmaVisibility();
384 case tok::annot_pragma_pack:
385 ProhibitAttributes(CXX11Attrs);
386 ProhibitAttributes(GNUAttrs);
390 case tok::annot_pragma_msstruct:
391 ProhibitAttributes(CXX11Attrs);
392 ProhibitAttributes(GNUAttrs);
393 HandlePragmaMSStruct();
396 case tok::annot_pragma_align:
397 ProhibitAttributes(CXX11Attrs);
398 ProhibitAttributes(GNUAttrs);
402 case tok::annot_pragma_weak:
403 ProhibitAttributes(CXX11Attrs);
404 ProhibitAttributes(GNUAttrs);
408 case tok::annot_pragma_weakalias:
409 ProhibitAttributes(CXX11Attrs);
410 ProhibitAttributes(GNUAttrs);
411 HandlePragmaWeakAlias();
414 case tok::annot_pragma_redefine_extname:
415 ProhibitAttributes(CXX11Attrs);
416 ProhibitAttributes(GNUAttrs);
417 HandlePragmaRedefineExtname();
420 case tok::annot_pragma_fp_contract:
421 ProhibitAttributes(CXX11Attrs);
422 ProhibitAttributes(GNUAttrs);
423 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
424 ConsumeAnnotationToken();
427 case tok::annot_pragma_fp:
428 ProhibitAttributes(CXX11Attrs);
429 ProhibitAttributes(GNUAttrs);
430 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
431 ConsumeAnnotationToken();
434 case tok::annot_pragma_fenv_access:
435 case tok::annot_pragma_fenv_access_ms:
436 ProhibitAttributes(CXX11Attrs);
437 ProhibitAttributes(GNUAttrs);
438 Diag(Tok, diag::err_pragma_file_or_compound_scope)
439 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
441 ConsumeAnnotationToken();
444 case tok::annot_pragma_fenv_round:
445 ProhibitAttributes(CXX11Attrs);
446 ProhibitAttributes(GNUAttrs);
447 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
448 ConsumeAnnotationToken();
451 case tok::annot_pragma_cx_limited_range:
452 ProhibitAttributes(CXX11Attrs);
453 ProhibitAttributes(GNUAttrs);
454 Diag(Tok, diag::err_pragma_file_or_compound_scope)
455 <<
"STDC CX_LIMITED_RANGE";
456 ConsumeAnnotationToken();
459 case tok::annot_pragma_float_control:
460 ProhibitAttributes(CXX11Attrs);
461 ProhibitAttributes(GNUAttrs);
462 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
463 ConsumeAnnotationToken();
466 case tok::annot_pragma_opencl_extension:
467 ProhibitAttributes(CXX11Attrs);
468 ProhibitAttributes(GNUAttrs);
469 HandlePragmaOpenCLExtension();
472 case tok::annot_pragma_captured:
473 ProhibitAttributes(CXX11Attrs);
474 ProhibitAttributes(GNUAttrs);
475 return HandlePragmaCaptured();
477 case tok::annot_pragma_openmp:
480 ProhibitAttributes(CXX11Attrs);
481 ProhibitAttributes(GNUAttrs);
483 case tok::annot_attr_openmp:
485 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
487 case tok::annot_pragma_openacc:
490 case tok::annot_pragma_ms_pointers_to_members:
491 ProhibitAttributes(CXX11Attrs);
492 ProhibitAttributes(GNUAttrs);
493 HandlePragmaMSPointersToMembers();
496 case tok::annot_pragma_ms_pragma:
497 ProhibitAttributes(CXX11Attrs);
498 ProhibitAttributes(GNUAttrs);
499 HandlePragmaMSPragma();
502 case tok::annot_pragma_ms_vtordisp:
503 ProhibitAttributes(CXX11Attrs);
504 ProhibitAttributes(GNUAttrs);
505 HandlePragmaMSVtorDisp();
508 case tok::annot_pragma_loop_hint:
509 ProhibitAttributes(CXX11Attrs);
510 ProhibitAttributes(GNUAttrs);
511 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);
513 case tok::annot_pragma_dump:
517 case tok::annot_pragma_attribute:
518 HandlePragmaAttribute();
527 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
536 StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
538 Token OldToken = Tok;
544 if (
Expr.isInvalid()) {
549 if (Tok.
is(tok::semi))
558 Diag(OldToken, diag::err_expected_case_before_expression)
562 return ParseCaseStatement(StmtCtx,
true,
Expr);
565 Token *CurTok =
nullptr;
570 if (Tok.
is(tok::annot_repl_input_end) && Actions.
getLangOpts().CPlusPlus)
574 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
577 if (CurTok && !R.isInvalid())
593 assert(Tok.
is(tok::kw___try) &&
"Expected '__try'");
596 if (Tok.
isNot(tok::l_brace))
597 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
602 if (TryBlock.isInvalid())
606 if (Tok.
is(tok::identifier) &&
609 Handler = ParseSEHExceptBlock(
Loc);
610 }
else if (Tok.
is(tok::kw___finally)) {
612 Handler = ParseSEHFinallyBlock(
Loc);
617 if(Handler.isInvalid())
633 raii2(Ident___exception_code,
false),
634 raii3(Ident_GetExceptionCode,
false);
636 if (ExpectAndConsume(tok::l_paren))
664 if (ExpectAndConsume(tok::r_paren))
667 if (Tok.
isNot(tok::l_brace))
668 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
672 if(
Block.isInvalid())
685 raii2(Ident___abnormal_termination,
false),
686 raii3(Ident_AbnormalTermination,
false);
688 if (Tok.
isNot(tok::l_brace))
689 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
691 ParseScope FinallyScope(
this, 0);
695 if(
Block.isInvalid()) {
716 if (!
P.getLangOpts().CPlusPlus && !
P.getLangOpts().MicrosoftExt &&
717 isa<DeclStmt>(SubStmt)) {
720 ? diag::warn_c23_compat_label_followed_by_declaration
721 : diag::ext_c_label_followed_by_declaration);
735 ParsedStmtContext StmtCtx) {
737 "Not an identifier!");
742 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
744 Token IdentTok = Tok;
747 assert(Tok.
is(tok::colon) &&
"Not a label!");
754 if (Tok.
is(tok::kw___attribute)) {
756 ParseGNUAttributes(TempAttrs);
770 SubStmt = ParseStatementOrDeclarationAfterAttributes(
771 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs, TempAttrs);
772 if (!TempAttrs.empty() && !SubStmt.isInvalid())
778 if (SubStmt.isUnset() && Tok.
is(tok::r_brace)) {
779 DiagnoseLabelAtEndOfCompoundStatement();
784 if (!SubStmt.isInvalid() && !SubStmt.isUsable())
785 SubStmt = ParseStatement(
nullptr, StmtCtx);
788 if (SubStmt.isInvalid())
807 StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
809 assert((MissingCase || Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
814 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
837 Stmt *DeepestParsedCaseStmt =
nullptr;
846 if (Tok.
is(tok::code_completion)) {
875 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
883 ColonProtection.restore();
889 Diag(ColonLoc, diag::err_expected_after)
890 <<
"'case'" << tok::colon
894 Diag(ExpectedLoc, diag::err_expected_after)
895 <<
"'case'" << tok::colon
897 ColonLoc = ExpectedLoc;
901 Actions.
ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
905 if (Case.isInvalid()) {
906 if (TopLevelCase.isInvalid())
907 return ParseStatement(
nullptr, StmtCtx);
912 Stmt *NextDeepest = Case.get();
913 if (TopLevelCase.isInvalid())
917 DeepestParsedCaseStmt = NextDeepest;
921 }
while (Tok.
is(tok::kw_case));
926 if (Tok.
is(tok::r_brace)) {
929 DiagnoseLabelAtEndOfCompoundStatement();
932 SubStmt = ParseStatement(
nullptr, StmtCtx);
936 if (DeepestParsedCaseStmt) {
938 if (SubStmt.isInvalid())
953 StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
954 assert(Tok.
is(tok::kw_default) &&
"Not a default stmt!");
959 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
967 Diag(ColonLoc, diag::err_expected_after)
968 <<
"'default'" << tok::colon
972 Diag(ExpectedLoc, diag::err_expected_after)
973 <<
"'default'" << tok::colon
975 ColonLoc = ExpectedLoc;
980 if (Tok.
is(tok::r_brace)) {
983 DiagnoseLabelAtEndOfCompoundStatement();
986 SubStmt = ParseStatement(
nullptr, StmtCtx);
990 if (SubStmt.isInvalid())
998 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
999 return ParseCompoundStatement(isStmtExpr,
1025 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
1026 unsigned ScopeFlags) {
1027 assert(Tok.
is(tok::l_brace) &&
"Not a compound stmt!");
1031 ParseScope CompoundScope(
this, ScopeFlags);
1034 return ParseCompoundStatementBody(isStmtExpr);
1040 void Parser::ParseCompoundStatementLeadingPragmas() {
1041 bool checkForPragmas =
true;
1042 while (checkForPragmas) {
1044 case tok::annot_pragma_vis:
1045 HandlePragmaVisibility();
1047 case tok::annot_pragma_pack:
1050 case tok::annot_pragma_msstruct:
1051 HandlePragmaMSStruct();
1053 case tok::annot_pragma_align:
1054 HandlePragmaAlign();
1056 case tok::annot_pragma_weak:
1059 case tok::annot_pragma_weakalias:
1060 HandlePragmaWeakAlias();
1062 case tok::annot_pragma_redefine_extname:
1063 HandlePragmaRedefineExtname();
1065 case tok::annot_pragma_opencl_extension:
1066 HandlePragmaOpenCLExtension();
1068 case tok::annot_pragma_fp_contract:
1069 HandlePragmaFPContract();
1071 case tok::annot_pragma_fp:
1074 case tok::annot_pragma_fenv_access:
1075 case tok::annot_pragma_fenv_access_ms:
1076 HandlePragmaFEnvAccess();
1078 case tok::annot_pragma_fenv_round:
1079 HandlePragmaFEnvRound();
1081 case tok::annot_pragma_cx_limited_range:
1082 HandlePragmaCXLimitedRange();
1084 case tok::annot_pragma_float_control:
1085 HandlePragmaFloatControl();
1087 case tok::annot_pragma_ms_pointers_to_members:
1088 HandlePragmaMSPointersToMembers();
1090 case tok::annot_pragma_ms_pragma:
1091 HandlePragmaMSPragma();
1093 case tok::annot_pragma_ms_vtordisp:
1094 HandlePragmaMSVtorDisp();
1096 case tok::annot_pragma_dump:
1100 checkForPragmas =
false;
1107 void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1110 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1111 : diag::ext_cxx_label_end_of_compound_statement);
1114 ? diag::warn_c23_compat_label_end_of_compound_statement
1115 : diag::ext_c_label_end_of_compound_statement);
1121 bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1122 if (!Tok.
is(tok::semi))
1134 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1136 Stmts.push_back(R.get());
1143 Diag(StartLoc, diag::warn_null_statement)
1149 bool IsStmtExprResult =
false;
1150 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1152 unsigned LookAhead = 0;
1153 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
1159 IsStmtExprResult = GetLookAheadToken(LookAhead).
is(tok::r_brace) &&
1160 GetLookAheadToken(LookAhead + 1).
is(tok::r_paren);
1163 if (IsStmtExprResult)
1172 StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1175 "in compound statement ('{}')");
1183 if (
T.consumeOpen())
1189 ParseCompoundStatementLeadingPragmas();
1196 while (Tok.
is(tok::kw___label__)) {
1201 if (Tok.
isNot(tok::identifier)) {
1202 Diag(Tok, diag::err_expected) << tok::identifier;
1219 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1221 Stmts.push_back(R.get());
1224 ParsedStmtContext SubStmtCtx =
1225 ParsedStmtContext::Compound |
1226 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1228 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
1230 if (Tok.
is(tok::annot_pragma_unused)) {
1231 HandlePragmaUnused();
1235 if (ConsumeNullStmt(Stmts))
1239 if (Tok.
isNot(tok::kw___extension__)) {
1240 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1247 while (Tok.
is(tok::kw___extension__))
1251 MaybeParseCXX11Attributes(attrs,
true);
1254 if (isDeclarationStatement()) {
1262 attrs, DeclSpecAttrs);
1266 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1268 if (Res.isInvalid()) {
1275 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1276 R = handleExprStmt(Res, SubStmtCtx);
1283 Stmts.push_back(R.get());
1292 LangOptions::FPEvalMethodKind::FEM_Source))
1294 diag::warn_no_support_for_eval_method_source_on_m32);
1299 if (!
T.consumeClose()) {
1302 if (isStmtExpr && Tok.
is(tok::r_paren))
1303 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1309 if (
T.getCloseLocation().isValid())
1310 CloseLoc =
T.getCloseLocation();
1330 bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1341 Cond = ParseCXXCondition(InitStmt,
Loc, CK,
false);
1360 if (Tok.
isNot(tok::r_paren))
1366 Start, Tok.
getLocation() == Start ? Start : PrevTokLocation, {},
1375 LParenLoc =
T.getOpenLocation();
1376 RParenLoc =
T.getCloseLocation();
1381 while (Tok.
is(tok::r_paren)) {
1382 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1392 enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1394 struct MisleadingIndentationChecker {
1398 unsigned NumDirectives;
1399 MisleadingStatementKind
Kind;
1401 MisleadingIndentationChecker(
Parser &
P, MisleadingStatementKind K,
1403 :
P(
P), StmtLoc(SL), PrevLoc(
P.getCurToken().getLocation()),
1404 NumDirectives(
P.getPreprocessor().getNumDirectives()),
Kind(K),
1405 ShouldSkip(
P.getCurToken().is(tok::l_brace)) {
1406 if (!
P.MisleadingIndentationElseLoc.isInvalid()) {
1407 StmtLoc =
P.MisleadingIndentationElseLoc;
1410 if (
Kind == MSK_else && !ShouldSkip)
1411 P.MisleadingIndentationElseLoc = SL;
1417 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1419 unsigned ColNo =
SM.getSpellingColumnNumber(
Loc);
1420 if (ColNo == 0 || TabStop == 1)
1423 std::pair<FileID, unsigned> FIDAndOffset =
SM.getDecomposedLoc(
Loc);
1426 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &Invalid);
1430 const char *EndPos = BufData.data() + FIDAndOffset.second;
1432 assert(FIDAndOffset.second + 1 >= ColNo &&
1433 "Column number smaller than file offset?");
1435 unsigned VisualColumn = 0;
1438 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1440 if (*CurPos ==
'\t')
1442 VisualColumn += (TabStop - VisualColumn % TabStop);
1446 return VisualColumn + 1;
1450 Token Tok =
P.getCurToken();
1451 if (
P.getActions().getDiagnostics().isIgnored(
1452 diag::warn_misleading_indentation, Tok.
getLocation()) ||
1453 ShouldSkip || NumDirectives !=
P.getPreprocessor().getNumDirectives() ||
1457 (
Kind == MSK_else &&
P.MisleadingIndentationElseLoc.isInvalid())) {
1461 if (
Kind == MSK_else)
1465 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1466 unsigned CurColNum = getVisualIndentation(
SM, Tok.
getLocation());
1467 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1469 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1470 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1472 SM.getPresumedLineNumber(StmtLoc) !=
1474 (Tok.
isNot(tok::identifier) ||
1475 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1477 P.Diag(StmtLoc, diag::note_previous_statement);
1494 assert(Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1497 bool IsConstexpr =
false;
1498 bool IsConsteval =
false;
1502 if (Tok.
is(tok::kw_constexpr)) {
1504 : diag::ext_constexpr_if);
1508 if (Tok.
is(tok::exclaim)) {
1512 if (Tok.
is(tok::kw_consteval)) {
1514 : diag::ext_consteval_if);
1519 if (!IsConsteval && (NotLocation.
isValid() || Tok.
isNot(tok::l_paren))) {
1520 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1546 std::optional<bool> ConstexprCondition;
1549 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1559 bool IsBracedThen = Tok.
is(tok::l_brace);
1581 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1589 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1592 if (NotLocation.
isInvalid() && IsConsteval) {
1598 Actions, Context,
nullptr,
1600 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1603 if (Tok.
isNot(tok::kw_else))
1614 if (Tok.
is(tok::kw_else)) {
1615 if (TrailingElseLoc)
1631 Tok.
is(tok::l_brace));
1633 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1634 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1637 if (NotLocation.
isValid() && IsConsteval) {
1643 Actions, Context,
nullptr,
1645 ElseStmt = ParseStatement();
1647 if (ElseStmt.isUsable())
1652 }
else if (Tok.
is(tok::code_completion)) {
1656 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1657 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1665 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1666 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1667 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1673 auto IsCompoundStatement = [](
const Stmt *S) {
1674 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1675 S = Outer->getSubStmt();
1676 return isa_and_nonnull<clang::CompoundStmt>(S);
1679 if (!IsCompoundStatement(ThenStmt.get())) {
1680 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1684 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1685 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1692 if (ThenStmt.isInvalid())
1694 if (ElseStmt.isInvalid())
1700 else if (IsConsteval)
1704 return Actions.
ActOnIfStmt(IfLoc,
Kind, LParen, InitStmt.get(), Cond, RParen,
1705 ThenStmt.get(), ElseLoc, ElseStmt.get());
1713 assert(Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1716 if (Tok.
isNot(tok::l_paren)) {
1717 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1739 ParseScope SwitchScope(
this, ScopeFlags);
1746 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1751 SwitchLoc, LParen, InitStmt.get(), Cond, RParen);
1753 if (
Switch.isInvalid()) {
1758 if (Tok.
is(tok::l_brace)) {
1786 StmtResult Body(ParseStatement(TrailingElseLoc));
1800 assert(Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1804 if (Tok.
isNot(tok::l_paren)) {
1805 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1824 unsigned ScopeFlags;
1830 ParseScope WhileScope(
this, ScopeFlags);
1836 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1853 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1856 StmtResult Body(ParseStatement(TrailingElseLoc));
1858 if (Body.isUsable())
1864 if (Cond.
isInvalid() || Body.isInvalid())
1867 return Actions.
ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1875 assert(Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1880 unsigned ScopeFlags;
1886 ParseScope DoScope(
this, ScopeFlags);
1905 if (Tok.
isNot(tok::kw_while)) {
1906 if (!Body.isInvalid()) {
1907 Diag(Tok, diag::err_expected_while);
1908 Diag(DoLoc, diag::note_matching) <<
"'do'";
1915 if (Tok.
isNot(tok::l_paren)) {
1916 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1926 DiagnoseAndSkipCXX11Attributes();
1935 if (!Tok.
isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1938 Start, Start == Tok.
getLocation() ? Start : PrevTokLocation, {},
1944 if (Cond.
isInvalid() || Body.isInvalid())
1947 return Actions.
ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1948 Cond.
get(),
T.getCloseLocation());
1951 bool Parser::isForRangeIdentifier() {
1952 assert(Tok.
is(tok::identifier));
1955 if (Next.is(tok::colon))
1958 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1959 TentativeParsingAction PA(*
this);
1961 SkipCXX11Attributes();
1962 bool Result = Tok.
is(tok::colon);
1994 assert(Tok.
is(tok::kw_for) &&
"Not a for stmt!");
1998 if (Tok.
is(tok::kw_co_await))
2001 if (Tok.
isNot(tok::l_paren)) {
2002 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
2025 unsigned ScopeFlags = 0;
2029 ParseScope ForScope(
this, ScopeFlags);
2036 bool ForEach =
false;
2040 ForRangeInfo ForRangeInfo;
2043 if (Tok.
is(tok::code_completion)) {
2052 MaybeParseCXX11Attributes(attrs);
2057 if (Tok.
is(tok::semi)) {
2058 ProhibitAttributes(attrs);
2062 EmptyInitStmtSemiLoc = SemiLoc;
2065 isForRangeIdentifier()) {
2066 ProhibitAttributes(attrs);
2069 MaybeParseCXX11Attributes(attrs);
2072 if (Tok.
is(tok::l_brace))
2073 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2077 Diag(
Loc, diag::err_for_range_identifier)
2082 ForRangeInfo.LoopVar =
2084 }
else if (isForInitDeclaration()) {
2088 if (!C99orCXXorObjC) {
2089 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2090 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2094 if (Tok.
is(tok::kw_using)) {
2100 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
2103 DG = ParseSimpleDeclaration(
2105 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2107 if (ForRangeInfo.ParsedForRangeDecl()) {
2109 ? diag::warn_cxx98_compat_for_range
2110 : diag::ext_for_range);
2111 ForRangeInfo.LoopVar = FirstPart;
2113 }
else if (Tok.
is(tok::semi)) {
2115 }
else if ((ForEach = isTokIdentifier_in())) {
2120 if (Tok.
is(tok::code_completion)) {
2128 Diag(Tok, diag::err_expected_semi_for);
2132 ProhibitAttributes(attrs);
2135 ForEach = isTokIdentifier_in();
2138 if (!
Value.isInvalid()) {
2147 bool IsRangeBasedFor =
2148 getLangOpts().CPlusPlus11 && !ForEach && Tok.
is(tok::colon);
2153 if (Tok.
is(tok::semi)) {
2155 }
else if (ForEach) {
2158 if (Tok.
is(tok::code_completion)) {
2168 Diag(Tok, diag::err_for_range_expected_decl)
2169 << FirstPart.get()->getSourceRange();
2173 if (!
Value.isInvalid()) {
2174 Diag(Tok, diag::err_expected_semi_for);
2178 if (Tok.
is(tok::semi))
2185 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2188 if (Tok.
is(tok::semi)) {
2190 }
else if (Tok.
is(tok::r_paren)) {
2196 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2200 SecondPart = ParseCXXCondition(
2201 nullptr, ForLoc, CK,
2203 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2206 if (ForRangeInfo.ParsedForRangeDecl()) {
2207 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2208 : ForRangeInfo.ColonLoc,
2210 ? diag::warn_cxx17_compat_for_range_init_stmt
2211 : diag::ext_for_range_init_stmt)
2212 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2214 if (EmptyInitStmtSemiLoc.
isValid()) {
2215 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2224 Tok.
getLocation() == SecondPartStart ? SecondPartStart
2254 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2255 if (Tok.
isNot(tok::semi)) {
2257 Diag(Tok, diag::err_expected_semi_for);
2261 if (Tok.
is(tok::semi)) {
2265 if (Tok.
isNot(tok::r_paren)) {
2277 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2278 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2283 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2291 if (ForRangeInfo.ParsedForRangeDecl()) {
2295 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2296 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
2298 ForRangeInfo.LifetimeExtendTemps);
2299 }
else if (ForEach) {
2303 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2307 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2324 Tok.
is(tok::l_brace));
2333 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2336 StmtResult Body(ParseStatement(TrailingElseLoc));
2338 if (Body.isUsable())
2347 if (Body.isInvalid())
2354 if (ForRangeInfo.ParsedForRangeDecl())
2357 return Actions.
ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2358 SecondPart, ThirdPart,
T.getCloseLocation(),
2370 assert(Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
2374 if (Tok.
is(tok::identifier)) {
2379 }
else if (Tok.
is(tok::star)) {
2381 Diag(Tok, diag::ext_gnu_indirect_goto);
2384 if (R.isInvalid()) {
2390 Diag(Tok, diag::err_expected) << tok::identifier;
2403 StmtResult Parser::ParseContinueStatement() {
2426 assert((Tok.
is(tok::kw_return) || Tok.
is(tok::kw_co_return)) &&
2427 "Not a return stmt!");
2428 bool IsCoreturn = Tok.
is(tok::kw_co_return);
2432 if (Tok.
isNot(tok::semi)) {
2436 if (Tok.
is(tok::code_completion) && !IsCoreturn) {
2444 R = ParseInitializer();
2448 ? diag::warn_cxx98_compat_generalized_initializer_lists
2449 : diag::ext_generalized_initializer_lists)
2463 StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2464 ParsedStmtContext StmtCtx,
2473 while (Tok.
is(tok::annot_pragma_loop_hint)) {
2475 if (!HandlePragmaLoopHint(Hint))
2486 MaybeParseCXX11Attributes(Attrs);
2489 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2490 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);
2502 Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2503 assert(Tok.
is(tok::l_brace));
2507 "parsing function body");
2513 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2518 StmtResult FnBody(ParseCompoundStatementBody());
2521 if (FnBody.isInvalid()) {
2536 Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2537 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2541 "parsing function try block");
2544 if (Tok.
is(tok::colon))
2545 ParseConstructorInitializer(
Decl);
2553 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2556 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2559 if (FnBody.isInvalid()) {
2569 bool Parser::trySkippingFunctionBody() {
2570 assert(SkipFunctionBodies &&
2571 "Should only be called when SkipFunctionBodies is enabled");
2579 TentativeParsingAction PA(*
this);
2580 bool IsTryCatch = Tok.
is(tok::kw_try);
2582 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2583 if (llvm::any_of(Toks, [](
const Token &Tok) {
2584 return Tok.
is(tok::code_completion);
2589 if (ErrorInPrologue) {
2598 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2615 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2618 return ParseCXXTryBlockCommon(TryLoc);
2638 if (Tok.
isNot(tok::l_brace))
2639 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2645 if (TryBlock.isInvalid())
2650 if ((Tok.
is(tok::identifier) &&
2652 Tok.
is(tok::kw___finally)) {
2657 Handler = ParseSEHExceptBlock(
Loc);
2661 Handler = ParseSEHFinallyBlock(
Loc);
2663 if(Handler.isInvalid())
2676 DiagnoseAndSkipCXX11Attributes();
2678 if (Tok.
isNot(tok::kw_catch))
2680 while (Tok.
is(tok::kw_catch)) {
2681 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2682 if (!Handler.isInvalid())
2683 Handlers.push_back(Handler.get());
2687 if (Handlers.empty())
2704 StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2705 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2710 if (
T.expectAndConsume())
2722 Decl *ExceptionDecl =
nullptr;
2723 if (Tok.
isNot(tok::ellipsis)) {
2725 MaybeParseCXX11Attributes(Attributes);
2729 if (ParseCXXTypeSpecifierSeq(DS))
2733 ParseDeclarator(ExDecl);
2739 if (
T.getCloseLocation().isInvalid())
2742 if (Tok.
isNot(tok::l_brace))
2743 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2747 if (
Block.isInvalid())
2753 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2754 IfExistsCondition Result;
2755 if (ParseMicrosoftIfExistsCondition(Result))
2762 if (Result.Behavior == IEB_Dependent) {
2763 if (!Tok.
is(tok::l_brace)) {
2764 Diag(Tok, diag::err_expected) << tok::l_brace;
2768 StmtResult Compound = ParseCompoundStatement();
2769 if (Compound.isInvalid())
2777 if (DepResult.isUsable())
2778 Stmts.push_back(DepResult.get());
2783 if (
Braces.consumeOpen()) {
2784 Diag(Tok, diag::err_expected) << tok::l_brace;
2788 switch (Result.Behavior) {
2794 llvm_unreachable(
"Dependent case handled above");
2802 while (Tok.
isNot(tok::r_brace)) {
2804 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2806 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 facilities that support code completion.
This file declares semantic analysis for Objective-C.
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.
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)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Sema::FullExprArg FullExprArg
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
Scope * getCurScope() const
StmtResult ParseOpenACCDirectiveStmt()
bool TryConsumeToken(tok::TokenKind Expected)
const LangOptions & getLangOpts() const
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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...
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.
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
SourceManager & getSourceManager() const
LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() 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.
const TargetInfo & getTargetInfo() const
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.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void CodeCompleteCase(Scope *S)
void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data)
Perform code-completion in an expression context when we know what type we're looking for.
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar)
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
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)
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
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)
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
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)
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
const LangOptions & getLangOpts() const
StmtResult ActOnExprStmtError()
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
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)
ASTContext & getASTContext() const
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)
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
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)
SemaCodeCompletion & CodeCompletion()
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.
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.
IdentifierInfo * getIdentifierInfo() const
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.
static SymbolFlags getFlags(bool WeakDef, bool ThreadLocal=false)
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.
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