30#include "llvm/ADT/STLExtras.h"
42 ParsedStmtContext StmtCtx) {
49 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
105Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
106 ParsedStmtContext StmtCtx,
117 MaybeParseCXX11Attributes(CXX11Attrs,
true);
120 MaybeParseGNUAttributes(GNUOrMSAttrs);
123 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);
125 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
126 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs);
127 MaybeDestroyTemplateIds();
135 "attributes on empty statement");
146 StatementFilterCCC(
Token nextTok) : NextToken(nextTok) {
147 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
148 tok::identifier, tok::star, tok::amp);
149 WantExpressionKeywords =
150 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
151 WantRemainingKeywords =
152 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
153 WantCXXNamedCasts =
false;
156 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
159 if (NextToken.is(tok::equal))
161 if (NextToken.is(tok::period) &&
167 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
168 return std::make_unique<StatementFilterCCC>(*
this);
176StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
177 StmtVector &Stmts, ParsedStmtContext StmtCtx,
180 const char *SemiError =
nullptr;
194 return ParseObjCAtStatement(AtLoc, StmtCtx);
197 case tok::code_completion:
203 case tok::identifier:
206 if (Next.is(tok::colon)) {
214 return ParseLabeledStatement(Attrs, StmtCtx);
219 if (Next.isNot(tok::coloncolon)) {
222 StatementFilterCCC CCC(Next);
223 if (TryAnnotateName(&CCC) == ANK_Error) {
227 if (Tok.
is(tok::semi))
233 if (Tok.
isNot(tok::identifier))
242 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
244 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
245 llvm::all_of(GNUAttrs, IsStmtAttr);
252 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
253 ParsedStmtContext()) &&
254 ((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
255 isDeclarationStatement())) {
258 if (GNUAttributeLoc.
isValid()) {
259 DeclStart = GNUAttributeLoc;
261 GNUAttrs, &GNUAttributeLoc);
277 if (Tok.
is(tok::r_brace)) {
278 Diag(Tok, diag::err_expected_statement);
283#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
284#include "clang/Basic/TransformTypeTraits.def"
287 Diag(Tok, diag::ext_keyword_as_ident)
289 goto ParseIdentifier;
293 return ParseExprStatement(StmtCtx);
297 case tok::kw___attribute: {
299 ParseGNUAttributes(GNUAttrs);
303 case tok::kw_template: {
308 getAccessSpecifierIfPresent());
313 return ParseCaseStatement(StmtCtx);
314 case tok::kw_default:
315 return ParseDefaultStatement(StmtCtx);
318 return ParseCompoundStatement();
325 return ParseIfStatement(TrailingElseLoc);
327 return ParseSwitchStatement(TrailingElseLoc);
330 return ParseWhileStatement(TrailingElseLoc);
332 Res = ParseDoStatement();
333 SemiError =
"do/while";
336 return ParseForStatement(TrailingElseLoc);
339 Res = ParseGotoStatement();
342 case tok::kw_continue:
343 Res = ParseContinueStatement();
344 SemiError =
"continue";
347 Res = ParseBreakStatement();
351 Res = ParseReturnStatement();
352 SemiError =
"return";
354 case tok::kw_co_return:
355 Res = ParseReturnStatement();
356 SemiError =
"co_return";
363 (AL.isRegularKeywordAttribute()
364 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
365 :
Diag(AL.
getRange().getBegin(), diag::warn_attribute_ignored))
369 ProhibitAttributes(GNUAttrs);
371 Res = ParseAsmStatement(msAsm);
372 if (msAsm)
return Res;
377 case tok::kw___if_exists:
378 case tok::kw___if_not_exists:
379 ProhibitAttributes(CXX11Attrs);
380 ProhibitAttributes(GNUAttrs);
381 ParseMicrosoftIfExistsStatement(Stmts);
387 return ParseCXXTryBlock();
390 ProhibitAttributes(CXX11Attrs);
391 ProhibitAttributes(GNUAttrs);
392 return ParseSEHTryBlock();
394 case tok::kw___leave:
395 Res = ParseSEHLeaveStatement();
396 SemiError =
"__leave";
399 case tok::annot_pragma_vis:
400 ProhibitAttributes(CXX11Attrs);
401 ProhibitAttributes(GNUAttrs);
402 HandlePragmaVisibility();
405 case tok::annot_pragma_pack:
406 ProhibitAttributes(CXX11Attrs);
407 ProhibitAttributes(GNUAttrs);
411 case tok::annot_pragma_msstruct:
412 ProhibitAttributes(CXX11Attrs);
413 ProhibitAttributes(GNUAttrs);
414 HandlePragmaMSStruct();
417 case tok::annot_pragma_align:
418 ProhibitAttributes(CXX11Attrs);
419 ProhibitAttributes(GNUAttrs);
423 case tok::annot_pragma_weak:
424 ProhibitAttributes(CXX11Attrs);
425 ProhibitAttributes(GNUAttrs);
429 case tok::annot_pragma_weakalias:
430 ProhibitAttributes(CXX11Attrs);
431 ProhibitAttributes(GNUAttrs);
432 HandlePragmaWeakAlias();
435 case tok::annot_pragma_redefine_extname:
436 ProhibitAttributes(CXX11Attrs);
437 ProhibitAttributes(GNUAttrs);
438 HandlePragmaRedefineExtname();
441 case tok::annot_pragma_fp_contract:
442 ProhibitAttributes(CXX11Attrs);
443 ProhibitAttributes(GNUAttrs);
444 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
445 ConsumeAnnotationToken();
448 case tok::annot_pragma_fp:
449 ProhibitAttributes(CXX11Attrs);
450 ProhibitAttributes(GNUAttrs);
451 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
452 ConsumeAnnotationToken();
455 case tok::annot_pragma_fenv_access:
456 case tok::annot_pragma_fenv_access_ms:
457 ProhibitAttributes(CXX11Attrs);
458 ProhibitAttributes(GNUAttrs);
459 Diag(Tok, diag::err_pragma_file_or_compound_scope)
460 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
462 ConsumeAnnotationToken();
465 case tok::annot_pragma_fenv_round:
466 ProhibitAttributes(CXX11Attrs);
467 ProhibitAttributes(GNUAttrs);
468 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
469 ConsumeAnnotationToken();
472 case tok::annot_pragma_cx_limited_range:
473 ProhibitAttributes(CXX11Attrs);
474 ProhibitAttributes(GNUAttrs);
475 Diag(Tok, diag::err_pragma_file_or_compound_scope)
476 <<
"STDC CX_LIMITED_RANGE";
477 ConsumeAnnotationToken();
480 case tok::annot_pragma_float_control:
481 ProhibitAttributes(CXX11Attrs);
482 ProhibitAttributes(GNUAttrs);
483 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
484 ConsumeAnnotationToken();
487 case tok::annot_pragma_opencl_extension:
488 ProhibitAttributes(CXX11Attrs);
489 ProhibitAttributes(GNUAttrs);
490 HandlePragmaOpenCLExtension();
493 case tok::annot_pragma_captured:
494 ProhibitAttributes(CXX11Attrs);
495 ProhibitAttributes(GNUAttrs);
496 return HandlePragmaCaptured();
498 case tok::annot_pragma_openmp:
501 ProhibitAttributes(CXX11Attrs);
502 ProhibitAttributes(GNUAttrs);
504 case tok::annot_attr_openmp:
506 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
508 case tok::annot_pragma_openacc:
511 case tok::annot_pragma_ms_pointers_to_members:
512 ProhibitAttributes(CXX11Attrs);
513 ProhibitAttributes(GNUAttrs);
514 HandlePragmaMSPointersToMembers();
517 case tok::annot_pragma_ms_pragma:
518 ProhibitAttributes(CXX11Attrs);
519 ProhibitAttributes(GNUAttrs);
520 HandlePragmaMSPragma();
523 case tok::annot_pragma_ms_vtordisp:
524 ProhibitAttributes(CXX11Attrs);
525 ProhibitAttributes(GNUAttrs);
526 HandlePragmaMSVtorDisp();
529 case tok::annot_pragma_loop_hint:
530 ProhibitAttributes(CXX11Attrs);
531 ProhibitAttributes(GNUAttrs);
532 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);
534 case tok::annot_pragma_dump:
538 case tok::annot_pragma_attribute:
539 HandlePragmaAttribute();
548 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
557StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
559 Token OldToken = Tok;
565 if (
Expr.isInvalid()) {
570 if (Tok.
is(tok::semi))
579 Diag(OldToken, diag::err_expected_case_before_expression)
583 return ParseCaseStatement(StmtCtx,
true,
Expr);
586 Token *CurTok =
nullptr;
588 if (Tok.
is(tok::annot_repl_input_end))
592 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
611 assert(Tok.
is(tok::kw___try) &&
"Expected '__try'");
614 if (Tok.
isNot(tok::l_brace))
615 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
620 if (TryBlock.isInvalid())
624 if (Tok.
is(tok::identifier) &&
627 Handler = ParseSEHExceptBlock(
Loc);
628 }
else if (Tok.
is(tok::kw___finally)) {
630 Handler = ParseSEHFinallyBlock(
Loc);
651 raii2(Ident___exception_code,
false),
652 raii3(Ident_GetExceptionCode,
false);
654 if (ExpectAndConsume(tok::l_paren))
668 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
682 if (ExpectAndConsume(tok::r_paren))
685 if (Tok.
isNot(tok::l_brace))
686 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
690 if(
Block.isInvalid())
703 raii2(Ident___abnormal_termination,
false),
704 raii3(Ident_AbnormalTermination,
false);
706 if (Tok.
isNot(tok::l_brace))
707 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
709 ParseScope FinallyScope(
this, 0);
713 if(
Block.isInvalid()) {
734 if (!
P.getLangOpts().CPlusPlus && !
P.getLangOpts().MicrosoftExt &&
735 isa<DeclStmt>(SubStmt)) {
738 ? diag::warn_c23_compat_label_followed_by_declaration
739 : diag::ext_c_label_followed_by_declaration);
753 ParsedStmtContext StmtCtx) {
755 "Not an identifier!");
760 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
762 Token IdentTok = Tok;
765 assert(Tok.
is(tok::colon) &&
"Not a label!");
772 if (Tok.
is(tok::kw___attribute)) {
774 ParseGNUAttributes(TempAttrs);
788 SubStmt = ParseStatementOrDeclarationAfterAttributes(
789 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs, TempAttrs);
790 if (!TempAttrs.empty() && !SubStmt.
isInvalid())
796 if (SubStmt.
isUnset() && Tok.
is(tok::r_brace)) {
797 DiagnoseLabelAtEndOfCompoundStatement();
803 SubStmt = ParseStatement(
nullptr, StmtCtx);
825StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
827 assert((MissingCase || Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
832 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
855 Stmt *DeepestParsedCaseStmt =
nullptr;
864 if (Tok.
is(tok::code_completion)) {
896 DiagId = diag::ext_gnu_case_range;
898 DiagId = diag::warn_c23_compat_case_range;
900 DiagId = diag::ext_c2y_case_range;
901 Diag(DotDotDotLoc, DiagId);
909 ColonProtection.restore();
915 Diag(ColonLoc, diag::err_expected_after)
916 <<
"'case'" << tok::colon
920 Diag(ExpectedLoc, diag::err_expected_after)
921 <<
"'case'" << tok::colon
923 ColonLoc = ExpectedLoc;
927 Actions.
ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
932 if (TopLevelCase.isInvalid())
933 return ParseStatement(
nullptr, StmtCtx);
938 Stmt *NextDeepest = Case.
get();
939 if (TopLevelCase.isInvalid())
943 DeepestParsedCaseStmt = NextDeepest;
947 }
while (Tok.
is(tok::kw_case));
952 if (Tok.
is(tok::r_brace)) {
955 DiagnoseLabelAtEndOfCompoundStatement();
958 SubStmt = ParseStatement(
nullptr, StmtCtx);
962 if (DeepestParsedCaseStmt) {
979StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
980 assert(Tok.
is(tok::kw_default) &&
"Not a default stmt!");
985 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
993 Diag(ColonLoc, diag::err_expected_after)
994 <<
"'default'" << tok::colon
998 Diag(ExpectedLoc, diag::err_expected_after)
999 <<
"'default'" << tok::colon
1001 ColonLoc = ExpectedLoc;
1006 if (Tok.
is(tok::r_brace)) {
1009 DiagnoseLabelAtEndOfCompoundStatement();
1012 SubStmt = ParseStatement(
nullptr, StmtCtx);
1024StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
1025 return ParseCompoundStatement(isStmtExpr,
1051StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
1052 unsigned ScopeFlags) {
1053 assert(Tok.
is(tok::l_brace) &&
"Not a compound stmt!");
1057 ParseScope CompoundScope(
this, ScopeFlags);
1060 return ParseCompoundStatementBody(isStmtExpr);
1066void Parser::ParseCompoundStatementLeadingPragmas() {
1067 bool checkForPragmas =
true;
1068 while (checkForPragmas) {
1070 case tok::annot_pragma_vis:
1071 HandlePragmaVisibility();
1073 case tok::annot_pragma_pack:
1076 case tok::annot_pragma_msstruct:
1077 HandlePragmaMSStruct();
1079 case tok::annot_pragma_align:
1080 HandlePragmaAlign();
1082 case tok::annot_pragma_weak:
1085 case tok::annot_pragma_weakalias:
1086 HandlePragmaWeakAlias();
1088 case tok::annot_pragma_redefine_extname:
1089 HandlePragmaRedefineExtname();
1091 case tok::annot_pragma_opencl_extension:
1092 HandlePragmaOpenCLExtension();
1094 case tok::annot_pragma_fp_contract:
1095 HandlePragmaFPContract();
1097 case tok::annot_pragma_fp:
1100 case tok::annot_pragma_fenv_access:
1101 case tok::annot_pragma_fenv_access_ms:
1102 HandlePragmaFEnvAccess();
1104 case tok::annot_pragma_fenv_round:
1105 HandlePragmaFEnvRound();
1107 case tok::annot_pragma_cx_limited_range:
1108 HandlePragmaCXLimitedRange();
1110 case tok::annot_pragma_float_control:
1111 HandlePragmaFloatControl();
1113 case tok::annot_pragma_ms_pointers_to_members:
1114 HandlePragmaMSPointersToMembers();
1116 case tok::annot_pragma_ms_pragma:
1117 HandlePragmaMSPragma();
1119 case tok::annot_pragma_ms_vtordisp:
1120 HandlePragmaMSVtorDisp();
1122 case tok::annot_pragma_dump:
1126 checkForPragmas =
false;
1133void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1136 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1137 : diag::ext_cxx_label_end_of_compound_statement);
1140 ? diag::warn_c23_compat_label_end_of_compound_statement
1141 : diag::ext_c_label_end_of_compound_statement);
1147bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1148 if (!Tok.
is(tok::semi))
1160 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1162 Stmts.push_back(R.
get());
1169 Diag(StartLoc, diag::warn_null_statement)
1175 bool IsStmtExprResult =
false;
1176 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1178 unsigned LookAhead = 0;
1179 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
1185 IsStmtExprResult = GetLookAheadToken(LookAhead).
is(tok::r_brace) &&
1186 GetLookAheadToken(LookAhead + 1).
is(tok::r_paren);
1189 if (IsStmtExprResult)
1198StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1201 "in compound statement ('{}')");
1209 if (
T.consumeOpen())
1215 ParseCompoundStatementLeadingPragmas();
1222 while (Tok.
is(tok::kw___label__)) {
1227 if (Tok.
isNot(tok::identifier)) {
1228 Diag(Tok, diag::err_expected) << tok::identifier;
1245 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1247 Stmts.push_back(R.
get());
1250 ParsedStmtContext SubStmtCtx =
1251 ParsedStmtContext::Compound |
1252 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1254 bool LastIsError =
false;
1255 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
1256 Tok.
isNot(tok::eof)) {
1257 if (Tok.
is(tok::annot_pragma_unused)) {
1258 HandlePragmaUnused();
1262 if (ConsumeNullStmt(Stmts))
1266 if (Tok.
isNot(tok::kw___extension__)) {
1267 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1274 while (Tok.
is(tok::kw___extension__))
1278 MaybeParseCXX11Attributes(attrs,
true);
1281 if (isDeclarationStatement()) {
1289 attrs, DeclSpecAttrs);
1293 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1295 if (Res.isInvalid()) {
1302 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1303 R = handleExprStmt(Res, SubStmtCtx);
1310 Stmts.push_back(R.
get());
1317 if (isStmtExpr && LastIsError && !Stmts.empty())
1329 diag::warn_no_support_for_eval_method_source_on_m32);
1334 if (!
T.consumeClose()) {
1337 if (isStmtExpr && Tok.
is(tok::r_paren))
1338 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1344 if (
T.getCloseLocation().isValid())
1345 CloseLoc =
T.getCloseLocation();
1365bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1376 Cond = ParseCXXCondition(InitStmt,
Loc, CK,
false);
1395 if (Tok.
isNot(tok::r_paren))
1401 Start, Tok.
getLocation() == Start ? Start : PrevTokLocation, {},
1410 LParenLoc =
T.getOpenLocation();
1411 RParenLoc =
T.getCloseLocation();
1416 while (Tok.
is(tok::r_paren)) {
1417 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1427enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1429struct MisleadingIndentationChecker {
1433 unsigned NumDirectives;
1434 MisleadingStatementKind
Kind;
1436 MisleadingIndentationChecker(
Parser &
P, MisleadingStatementKind K,
1438 :
P(
P), StmtLoc(SL), PrevLoc(
P.getCurToken().getLocation()),
1439 NumDirectives(
P.getPreprocessor().getNumDirectives()),
Kind(K),
1440 ShouldSkip(
P.getCurToken().is(tok::l_brace)) {
1441 if (!
P.MisleadingIndentationElseLoc.isInvalid()) {
1442 StmtLoc =
P.MisleadingIndentationElseLoc;
1445 if (
Kind == MSK_else && !ShouldSkip)
1446 P.MisleadingIndentationElseLoc = SL;
1452 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1454 unsigned ColNo =
SM.getSpellingColumnNumber(
Loc);
1455 if (ColNo == 0 || TabStop == 1)
1458 std::pair<FileID, unsigned> FIDAndOffset =
SM.getDecomposedLoc(
Loc);
1461 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1465 const char *EndPos = BufData.data() + FIDAndOffset.second;
1467 assert(FIDAndOffset.second + 1 >= ColNo &&
1468 "Column number smaller than file offset?");
1470 unsigned VisualColumn = 0;
1473 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1475 if (*CurPos ==
'\t')
1477 VisualColumn += (TabStop - VisualColumn % TabStop);
1481 return VisualColumn + 1;
1485 Token Tok =
P.getCurToken();
1486 if (
P.getActions().getDiagnostics().isIgnored(
1487 diag::warn_misleading_indentation, Tok.
getLocation()) ||
1488 ShouldSkip || NumDirectives !=
P.getPreprocessor().getNumDirectives() ||
1492 (
Kind == MSK_else &&
P.MisleadingIndentationElseLoc.isInvalid())) {
1496 if (
Kind == MSK_else)
1500 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1501 unsigned CurColNum = getVisualIndentation(
SM, Tok.
getLocation());
1502 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1504 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1505 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1507 SM.getPresumedLineNumber(StmtLoc) !=
1509 (Tok.
isNot(tok::identifier) ||
1510 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1512 P.Diag(StmtLoc, diag::note_previous_statement);
1529 assert(Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1532 bool IsConstexpr =
false;
1533 bool IsConsteval =
false;
1537 if (Tok.
is(tok::kw_constexpr)) {
1541 : diag::ext_constexpr_if);
1546 if (Tok.
is(tok::exclaim)) {
1550 if (Tok.
is(tok::kw_consteval)) {
1552 : diag::ext_consteval_if);
1557 if (!IsConsteval && (NotLocation.
isValid() || Tok.
isNot(tok::l_paren))) {
1558 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1584 std::optional<bool> ConstexprCondition;
1587 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1597 bool IsBracedThen = Tok.
is(tok::l_brace);
1619 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1627 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1630 if (NotLocation.
isInvalid() && IsConsteval) {
1636 Actions, Context,
nullptr,
1638 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1641 if (Tok.
isNot(tok::kw_else))
1652 if (Tok.
is(tok::kw_else)) {
1653 if (TrailingElseLoc)
1669 Tok.
is(tok::l_brace));
1671 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1672 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1675 if (NotLocation.
isValid() && IsConsteval) {
1681 Actions, Context,
nullptr,
1683 ElseStmt = ParseStatement();
1690 }
else if (Tok.
is(tok::code_completion)) {
1694 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1695 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1711 auto IsCompoundStatement = [](
const Stmt *S) {
1712 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1713 S = Outer->getSubStmt();
1714 return isa_and_nonnull<clang::CompoundStmt>(S);
1717 if (!IsCompoundStatement(ThenStmt.
get())) {
1718 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1722 if (!ElseStmt.
isUnset() && !IsCompoundStatement(ElseStmt.
get())) {
1723 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1738 else if (IsConsteval)
1742 return Actions.
ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.
get(), Cond, RParen,
1743 ThenStmt.
get(), ElseLoc, ElseStmt.
get());
1751 assert(Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1754 if (Tok.
isNot(tok::l_paren)) {
1755 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1777 ParseScope SwitchScope(
this, ScopeFlags);
1784 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1789 SwitchLoc, LParen, InitStmt.
get(), Cond, RParen);
1791 if (
Switch.isInvalid()) {
1796 if (Tok.
is(tok::l_brace)) {
1824 StmtResult Body(ParseStatement(TrailingElseLoc));
1838 assert(Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1842 if (Tok.
isNot(tok::l_paren)) {
1843 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1862 unsigned ScopeFlags;
1868 ParseScope WhileScope(
this, ScopeFlags);
1874 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1896 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1899 StmtResult Body(ParseStatement(TrailingElseLoc));
1901 if (Body.isUsable())
1907 if (Cond.
isInvalid() || Body.isInvalid())
1910 return Actions.
ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1918 assert(Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1923 unsigned ScopeFlags;
1929 ParseScope DoScope(
this, ScopeFlags);
1953 if (Tok.
isNot(tok::kw_while)) {
1954 if (!Body.isInvalid()) {
1955 Diag(Tok, diag::err_expected_while);
1956 Diag(DoLoc, diag::note_matching) <<
"'do'";
1963 if (Tok.
isNot(tok::l_paren)) {
1964 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1974 DiagnoseAndSkipCXX11Attributes();
1983 if (!Tok.
isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1986 Start, Start == Tok.
getLocation() ? Start : PrevTokLocation, {},
1992 if (Cond.
isInvalid() || Body.isInvalid())
1995 return Actions.
ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1996 Cond.
get(),
T.getCloseLocation());
1999bool Parser::isForRangeIdentifier() {
2000 assert(Tok.
is(tok::identifier));
2003 if (Next.is(tok::colon))
2006 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
2007 TentativeParsingAction PA(*
this);
2009 SkipCXX11Attributes();
2042 assert(Tok.
is(tok::kw_for) &&
"Not a for stmt!");
2046 if (Tok.
is(tok::kw_co_await))
2049 if (Tok.
isNot(tok::l_paren)) {
2050 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
2073 unsigned ScopeFlags = 0;
2077 ParseScope ForScope(
this, ScopeFlags);
2084 bool ForEach =
false;
2088 ForRangeInfo ForRangeInfo;
2091 if (Tok.
is(tok::code_completion)) {
2100 MaybeParseCXX11Attributes(attrs);
2105 if (Tok.
is(tok::semi)) {
2106 ProhibitAttributes(attrs);
2110 EmptyInitStmtSemiLoc = SemiLoc;
2113 isForRangeIdentifier()) {
2114 ProhibitAttributes(attrs);
2117 MaybeParseCXX11Attributes(attrs);
2120 if (Tok.
is(tok::l_brace))
2121 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2125 Diag(
Loc, diag::err_for_range_identifier)
2130 ForRangeInfo.LoopVar =
2132 }
else if (isForInitDeclaration()) {
2136 if (!C99orCXXorObjC) {
2137 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2138 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2142 if (Tok.
is(tok::kw_using)) {
2148 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
2151 DG = ParseSimpleDeclaration(
2153 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2155 if (ForRangeInfo.ParsedForRangeDecl()) {
2157 ? diag::warn_cxx98_compat_for_range
2158 : diag::ext_for_range);
2159 ForRangeInfo.LoopVar = FirstPart;
2161 }
else if (Tok.
is(tok::semi)) {
2163 }
else if ((ForEach = isTokIdentifier_in())) {
2168 if (Tok.
is(tok::code_completion)) {
2176 Diag(Tok, diag::err_expected_semi_for);
2180 ProhibitAttributes(attrs);
2183 ForEach = isTokIdentifier_in();
2186 if (!
Value.isInvalid()) {
2195 bool IsRangeBasedFor =
2196 getLangOpts().CPlusPlus11 && !ForEach && Tok.
is(tok::colon);
2201 if (Tok.
is(tok::semi)) {
2203 }
else if (ForEach) {
2206 if (Tok.
is(tok::code_completion)) {
2216 Diag(Tok, diag::err_for_range_expected_decl)
2221 if (!
Value.isInvalid()) {
2222 Diag(Tok, diag::err_expected_semi_for);
2226 if (Tok.
is(tok::semi))
2233 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2236 if (Tok.
is(tok::semi)) {
2238 }
else if (Tok.
is(tok::r_paren)) {
2244 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2248 SecondPart = ParseCXXCondition(
2249 nullptr, ForLoc, CK,
2251 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2254 if (ForRangeInfo.ParsedForRangeDecl()) {
2256 : ForRangeInfo.ColonLoc,
2258 ? diag::warn_cxx17_compat_for_range_init_stmt
2259 : diag::ext_for_range_init_stmt)
2262 if (EmptyInitStmtSemiLoc.
isValid()) {
2263 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2272 Tok.
getLocation() == SecondPartStart ? SecondPartStart
2302 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2303 if (Tok.
isNot(tok::semi)) {
2305 Diag(Tok, diag::err_expected_semi_for);
2309 if (Tok.
is(tok::semi)) {
2313 if (Tok.
isNot(tok::r_paren)) {
2325 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2326 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2331 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2339 if (ForRangeInfo.ParsedForRangeDecl()) {
2344 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
2346 ForRangeInfo.LifetimeExtendTemps);
2347 }
else if (ForEach) {
2351 ForLoc, FirstPart.
get(), Collection.
get(),
T.getCloseLocation());
2363 if (ForRangeInfo.ParsedForRangeDecl())
2367 ForLoc, FirstPart.
get(), SecondPart.
get().second, ThirdPart.get());
2381 Tok.
is(tok::l_brace));
2390 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2393 StmtResult Body(ParseStatement(TrailingElseLoc));
2395 if (Body.isUsable())
2406 if (Body.isInvalid())
2413 if (ForRangeInfo.ParsedForRangeDecl())
2417 SecondPart, ThirdPart,
T.getCloseLocation(),
2429 assert(Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
2433 if (Tok.
is(tok::identifier)) {
2438 }
else if (Tok.
is(tok::star)) {
2440 Diag(Tok, diag::ext_gnu_indirect_goto);
2449 Diag(Tok, diag::err_expected) << tok::identifier;
2485 assert((Tok.
is(tok::kw_return) || Tok.
is(tok::kw_co_return)) &&
2486 "Not a return stmt!");
2487 bool IsCoreturn = Tok.
is(tok::kw_co_return);
2491 if (Tok.
isNot(tok::semi)) {
2495 if (Tok.
is(tok::code_completion) && !IsCoreturn) {
2503 R = ParseInitializer();
2507 ? diag::warn_cxx98_compat_generalized_initializer_lists
2508 : diag::ext_generalized_initializer_lists)
2522StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2523 ParsedStmtContext StmtCtx,
2532 while (Tok.
is(tok::annot_pragma_loop_hint)) {
2534 if (!HandlePragmaLoopHint(Hint))
2541 ParsedAttr::Form::Pragma());
2545 MaybeParseCXX11Attributes(Attrs);
2548 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2549 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);
2561Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2562 assert(Tok.
is(tok::l_brace));
2566 "parsing function body");
2572 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2577 StmtResult FnBody(ParseCompoundStatementBody());
2580 if (FnBody.isInvalid()) {
2594Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2595 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2599 "parsing function try block");
2602 if (Tok.
is(tok::colon))
2603 ParseConstructorInitializer(
Decl);
2611 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2614 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2617 if (FnBody.isInvalid()) {
2626bool Parser::trySkippingFunctionBody() {
2627 assert(SkipFunctionBodies &&
2628 "Should only be called when SkipFunctionBodies is enabled");
2636 TentativeParsingAction PA(*
this);
2637 bool IsTryCatch = Tok.
is(tok::kw_try);
2639 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2640 if (llvm::any_of(Toks, [](
const Token &Tok) {
2641 return Tok.
is(tok::code_completion);
2646 if (ErrorInPrologue) {
2655 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2672 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2675 return ParseCXXTryBlockCommon(TryLoc);
2695 if (Tok.
isNot(tok::l_brace))
2696 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2702 if (TryBlock.isInvalid())
2707 if ((Tok.
is(tok::identifier) &&
2709 Tok.
is(tok::kw___finally)) {
2714 Handler = ParseSEHExceptBlock(
Loc);
2718 Handler = ParseSEHFinallyBlock(
Loc);
2733 DiagnoseAndSkipCXX11Attributes();
2735 if (Tok.
isNot(tok::kw_catch))
2737 while (Tok.
is(tok::kw_catch)) {
2738 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2740 Handlers.push_back(Handler.
get());
2744 if (Handlers.empty())
2761StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2762 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2767 if (
T.expectAndConsume())
2779 Decl *ExceptionDecl =
nullptr;
2780 if (Tok.
isNot(tok::ellipsis)) {
2782 MaybeParseCXX11Attributes(Attributes);
2786 if (ParseCXXTypeSpecifierSeq(DS))
2790 ParseDeclarator(ExDecl);
2796 if (
T.getCloseLocation().isInvalid())
2799 if (Tok.
isNot(tok::l_brace))
2800 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2804 if (
Block.isInvalid())
2810void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2811 IfExistsCondition
Result;
2812 if (ParseMicrosoftIfExistsCondition(
Result))
2819 if (
Result.Behavior == IEB_Dependent) {
2820 if (!Tok.
is(tok::l_brace)) {
2821 Diag(Tok, diag::err_expected) << tok::l_brace;
2825 StmtResult Compound = ParseCompoundStatement();
2835 Stmts.push_back(DepResult.
get());
2840 if (
Braces.consumeOpen()) {
2841 Diag(Tok, diag::err_expected) << tok::l_brace;
2845 switch (
Result.Behavior) {
2851 llvm_unreachable(
"Dependent case handled above");
2859 while (Tok.
isNot(tok::r_brace)) {
2861 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2863 Stmts.push_back(R.
get());
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
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 OpenACC constructs and clauses.
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.
Sema & getActions() const
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.
@ 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.
Helper type to restore the state of various 'loop' constructs when we run into a loop (for,...
void ActOnWhileStmt(SourceLocation WhileLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
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::pair< VarDecl *, Expr * > get() const
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)
ASTContext & getASTContext() const
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)
SemaCodeCompletion & CodeCompletion()
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)
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)
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)
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