1//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Statement and Block portions of the Parser
10// interface.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/PrettyDeclStackTrace.h"
15#include "clang/Basic/Attributes.h"
16#include "clang/Basic/PrettyStackTrace.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Basic/TokenKinds.h"
19#include "clang/Parse/LoopHint.h"
20#include "clang/Parse/Parser.h"
21#include "clang/Parse/RAIIObjectsForParser.h"
22#include "clang/Sema/DeclSpec.h"
23#include "clang/Sema/EnterExpressionEvaluationContext.h"
24#include "clang/Sema/Scope.h"
25#include "clang/Sema/TypoCorrection.h"
26#include "llvm/ADT/STLExtras.h"
27#include <optional>
28
29using namespace clang;
30
31//===----------------------------------------------------------------------===//
32// C99 6.8: Statements and Blocks.
33//===----------------------------------------------------------------------===//
34
35/// Parse a standalone statement (for instance, as the body of an 'if',
36/// 'while', or 'for').
37StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
38 ParsedStmtContext StmtCtx) {
39 StmtResult Res;
40
41 // We may get back a null statement if we found a #pragma. Keep going until
42 // we get an actual statement.
43 StmtVector Stmts;
44 do {
45 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
46 } while (!Res.isInvalid() && !Res.get());
47
48 return Res;
49}
50
51/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
52/// StatementOrDeclaration:
53/// statement
54/// declaration
55///
56/// statement:
57/// labeled-statement
58/// compound-statement
59/// expression-statement
60/// selection-statement
61/// iteration-statement
62/// jump-statement
63/// [C++] declaration-statement
64/// [C++] try-block
65/// [MS] seh-try-block
66/// [OBC] objc-throw-statement
67/// [OBC] objc-try-catch-statement
68/// [OBC] objc-synchronized-statement
69/// [GNU] asm-statement
70/// [OMP] openmp-construct [TODO]
71///
72/// labeled-statement:
73/// identifier ':' statement
74/// 'case' constant-expression ':' statement
75/// 'default' ':' statement
76///
77/// selection-statement:
78/// if-statement
79/// switch-statement
80///
81/// iteration-statement:
82/// while-statement
83/// do-statement
84/// for-statement
85///
86/// expression-statement:
87/// expression[opt] ';'
88///
89/// jump-statement:
90/// 'goto' identifier ';'
91/// 'continue' ';'
92/// 'break' ';'
93/// 'return' expression[opt] ';'
94/// [GNU] 'goto' '*' expression ';'
95///
96/// [OBC] objc-throw-statement:
97/// [OBC] '@' 'throw' expression ';'
98/// [OBC] '@' 'throw' ';'
99///
100StmtResult
101Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
102 ParsedStmtContext StmtCtx,
103 SourceLocation *TrailingElseLoc) {
104
105 ParenBraceBracketBalancer BalancerRAIIObj(*this);
106
107 // Because we're parsing either a statement or a declaration, the order of
108 // attribute parsing is important. [[]] attributes at the start of a
109 // statement are different from [[]] attributes that follow an __attribute__
110 // at the start of the statement. Thus, we're not using MaybeParseAttributes
111 // here because we don't want to allow arbitrary orderings.
112 ParsedAttributes CXX11Attrs(AttrFactory);
113 MaybeParseCXX11Attributes(Attrs&: CXX11Attrs, /*MightBeObjCMessageSend*/ OuterMightBeMessageSend: true);
114 ParsedAttributes GNUAttrs(AttrFactory);
115 if (getLangOpts().OpenCL)
116 MaybeParseGNUAttributes(Attrs&: GNUAttrs);
117
118 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
119 Stmts, StmtCtx, TrailingElseLoc, DeclAttrs&: CXX11Attrs, DeclSpecAttrs&: GNUAttrs);
120 MaybeDestroyTemplateIds();
121
122 // Attributes that are left should all go on the statement, so concatenate the
123 // two lists.
124 ParsedAttributes Attrs(AttrFactory);
125 takeAndConcatenateAttrs(First&: CXX11Attrs, Second&: GNUAttrs, Result&: Attrs);
126
127 assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
128 "attributes on empty statement");
129
130 if (Attrs.empty() || Res.isInvalid())
131 return Res;
132
133 return Actions.ActOnAttributedStmt(AttrList: Attrs, SubStmt: Res.get());
134}
135
136namespace {
137class StatementFilterCCC final : public CorrectionCandidateCallback {
138public:
139 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
140 WantTypeSpecifiers = nextTok.isOneOf(K1: tok::l_paren, Ks: tok::less, Ks: tok::l_square,
141 Ks: tok::identifier, Ks: tok::star, Ks: tok::amp);
142 WantExpressionKeywords =
143 nextTok.isOneOf(K1: tok::l_paren, Ks: tok::identifier, Ks: tok::arrow, Ks: tok::period);
144 WantRemainingKeywords =
145 nextTok.isOneOf(K1: tok::l_paren, Ks: tok::semi, Ks: tok::identifier, Ks: tok::l_brace);
146 WantCXXNamedCasts = false;
147 }
148
149 bool ValidateCandidate(const TypoCorrection &candidate) override {
150 if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
151 return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(Val: FD);
152 if (NextToken.is(K: tok::equal))
153 return candidate.getCorrectionDeclAs<VarDecl>();
154 if (NextToken.is(K: tok::period) &&
155 candidate.getCorrectionDeclAs<NamespaceDecl>())
156 return false;
157 return CorrectionCandidateCallback::ValidateCandidate(candidate);
158 }
159
160 std::unique_ptr<CorrectionCandidateCallback> clone() override {
161 return std::make_unique<StatementFilterCCC>(args&: *this);
162 }
163
164private:
165 Token NextToken;
166};
167}
168
169StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
170 StmtVector &Stmts, ParsedStmtContext StmtCtx,
171 SourceLocation *TrailingElseLoc, ParsedAttributes &CXX11Attrs,
172 ParsedAttributes &GNUAttrs) {
173 const char *SemiError = nullptr;
174 StmtResult Res;
175 SourceLocation GNUAttributeLoc;
176
177 // Cases in this switch statement should fall through if the parser expects
178 // the token to end in a semicolon (in which case SemiError should be set),
179 // or they directly 'return;' if not.
180Retry:
181 tok::TokenKind Kind = Tok.getKind();
182 SourceLocation AtLoc;
183 switch (Kind) {
184 case tok::at: // May be a @try or @throw statement
185 {
186 AtLoc = ConsumeToken(); // consume @
187 return ParseObjCAtStatement(atLoc: AtLoc, StmtCtx);
188 }
189
190 case tok::code_completion:
191 cutOffParsing();
192 Actions.CodeCompleteOrdinaryName(S: getCurScope(), CompletionContext: Sema::PCC_Statement);
193 return StmtError();
194
195 case tok::identifier:
196 ParseIdentifier: {
197 Token Next = NextToken();
198 if (Next.is(K: tok::colon)) { // C99 6.8.1: labeled-statement
199 // Both C++11 and GNU attributes preceding the label appertain to the
200 // label, so put them in a single list to pass on to
201 // ParseLabeledStatement().
202 ParsedAttributes Attrs(AttrFactory);
203 takeAndConcatenateAttrs(First&: CXX11Attrs, Second&: GNUAttrs, Result&: Attrs);
204
205 // identifier ':' statement
206 return ParseLabeledStatement(Attrs, StmtCtx);
207 }
208
209 // Look up the identifier, and typo-correct it to a keyword if it's not
210 // found.
211 if (Next.isNot(K: tok::coloncolon)) {
212 // Try to limit which sets of keywords should be included in typo
213 // correction based on what the next token is.
214 StatementFilterCCC CCC(Next);
215 if (TryAnnotateName(CCC: &CCC) == ANK_Error) {
216 // Handle errors here by skipping up to the next semicolon or '}', and
217 // eat the semicolon if that's what stopped us.
218 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
219 if (Tok.is(K: tok::semi))
220 ConsumeToken();
221 return StmtError();
222 }
223
224 // If the identifier was typo-corrected, try again.
225 if (Tok.isNot(K: tok::identifier))
226 goto Retry;
227 }
228
229 // Fall through
230 [[fallthrough]];
231 }
232
233 default: {
234 bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty();
235 auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); };
236 bool AllAttrsAreStmtAttrs = llvm::all_of(Range&: CXX11Attrs, P: IsStmtAttr) &&
237 llvm::all_of(Range&: GNUAttrs, P: IsStmtAttr);
238 if (((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
239 isDeclarationStatement())) {
240 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
241 DeclGroupPtrTy Decl;
242 if (GNUAttributeLoc.isValid()) {
243 DeclStart = GNUAttributeLoc;
244 Decl = ParseDeclaration(Context: DeclaratorContext::Block, DeclEnd, DeclAttrs&: CXX11Attrs,
245 DeclSpecAttrs&: GNUAttrs, DeclSpecStart: &GNUAttributeLoc);
246 } else {
247 Decl = ParseDeclaration(Context: DeclaratorContext::Block, DeclEnd, DeclAttrs&: CXX11Attrs,
248 DeclSpecAttrs&: GNUAttrs);
249 }
250 if (CXX11Attrs.Range.getBegin().isValid()) {
251 // The caller must guarantee that the CXX11Attrs appear before the
252 // GNUAttrs, and we rely on that here.
253 assert(GNUAttrs.Range.getBegin().isInvalid() ||
254 GNUAttrs.Range.getBegin() > CXX11Attrs.Range.getBegin());
255 DeclStart = CXX11Attrs.Range.getBegin();
256 } else if (GNUAttrs.Range.getBegin().isValid())
257 DeclStart = GNUAttrs.Range.getBegin();
258 return Actions.ActOnDeclStmt(Decl, StartLoc: DeclStart, EndLoc: DeclEnd);
259 }
260
261 if (Tok.is(K: tok::r_brace)) {
262 Diag(Tok, diag::err_expected_statement);
263 return StmtError();
264 }
265
266 switch (Tok.getKind()) {
267#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
268#include "clang/Basic/TransformTypeTraits.def"
269 if (NextToken().is(K: tok::less)) {
270 Tok.setKind(tok::identifier);
271 Diag(Tok, diag::ext_keyword_as_ident)
272 << Tok.getIdentifierInfo()->getName() << 0;
273 goto ParseIdentifier;
274 }
275 [[fallthrough]];
276 default:
277 return ParseExprStatement(StmtCtx);
278 }
279 }
280
281 case tok::kw___attribute: {
282 GNUAttributeLoc = Tok.getLocation();
283 ParseGNUAttributes(Attrs&: GNUAttrs);
284 goto Retry;
285 }
286
287 case tok::kw_case: // C99 6.8.1: labeled-statement
288 return ParseCaseStatement(StmtCtx);
289 case tok::kw_default: // C99 6.8.1: labeled-statement
290 return ParseDefaultStatement(StmtCtx);
291
292 case tok::l_brace: // C99 6.8.2: compound-statement
293 return ParseCompoundStatement();
294 case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
295 bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
296 return Actions.ActOnNullStmt(SemiLoc: ConsumeToken(), HasLeadingEmptyMacro);
297 }
298
299 case tok::kw_if: // C99 6.8.4.1: if-statement
300 return ParseIfStatement(TrailingElseLoc);
301 case tok::kw_switch: // C99 6.8.4.2: switch-statement
302 return ParseSwitchStatement(TrailingElseLoc);
303
304 case tok::kw_while: // C99 6.8.5.1: while-statement
305 return ParseWhileStatement(TrailingElseLoc);
306 case tok::kw_do: // C99 6.8.5.2: do-statement
307 Res = ParseDoStatement();
308 SemiError = "do/while";
309 break;
310 case tok::kw_for: // C99 6.8.5.3: for-statement
311 return ParseForStatement(TrailingElseLoc);
312
313 case tok::kw_goto: // C99 6.8.6.1: goto-statement
314 Res = ParseGotoStatement();
315 SemiError = "goto";
316 break;
317 case tok::kw_continue: // C99 6.8.6.2: continue-statement
318 Res = ParseContinueStatement();
319 SemiError = "continue";
320 break;
321 case tok::kw_break: // C99 6.8.6.3: break-statement
322 Res = ParseBreakStatement();
323 SemiError = "break";
324 break;
325 case tok::kw_return: // C99 6.8.6.4: return-statement
326 Res = ParseReturnStatement();
327 SemiError = "return";
328 break;
329 case tok::kw_co_return: // C++ Coroutines: co_return statement
330 Res = ParseReturnStatement();
331 SemiError = "co_return";
332 break;
333
334 case tok::kw_asm: {
335 for (const ParsedAttr &AL : CXX11Attrs)
336 // Could be relaxed if asm-related regular keyword attributes are
337 // added later.
338 (AL.isRegularKeywordAttribute()
339 ? Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
340 : Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))
341 << AL;
342 // Prevent these from being interpreted as statement attributes later on.
343 CXX11Attrs.clear();
344 ProhibitAttributes(Attrs&: GNUAttrs);
345 bool msAsm = false;
346 Res = ParseAsmStatement(msAsm);
347 if (msAsm) return Res;
348 SemiError = "asm";
349 break;
350 }
351
352 case tok::kw___if_exists:
353 case tok::kw___if_not_exists:
354 ProhibitAttributes(Attrs&: CXX11Attrs);
355 ProhibitAttributes(Attrs&: GNUAttrs);
356 ParseMicrosoftIfExistsStatement(Stmts);
357 // An __if_exists block is like a compound statement, but it doesn't create
358 // a new scope.
359 return StmtEmpty();
360
361 case tok::kw_try: // C++ 15: try-block
362 return ParseCXXTryBlock();
363
364 case tok::kw___try:
365 ProhibitAttributes(Attrs&: CXX11Attrs);
366 ProhibitAttributes(Attrs&: GNUAttrs);
367 return ParseSEHTryBlock();
368
369 case tok::kw___leave:
370 Res = ParseSEHLeaveStatement();
371 SemiError = "__leave";
372 break;
373
374 case tok::annot_pragma_vis:
375 ProhibitAttributes(Attrs&: CXX11Attrs);
376 ProhibitAttributes(Attrs&: GNUAttrs);
377 HandlePragmaVisibility();
378 return StmtEmpty();
379
380 case tok::annot_pragma_pack:
381 ProhibitAttributes(Attrs&: CXX11Attrs);
382 ProhibitAttributes(Attrs&: GNUAttrs);
383 HandlePragmaPack();
384 return StmtEmpty();
385
386 case tok::annot_pragma_msstruct:
387 ProhibitAttributes(Attrs&: CXX11Attrs);
388 ProhibitAttributes(Attrs&: GNUAttrs);
389 HandlePragmaMSStruct();
390 return StmtEmpty();
391
392 case tok::annot_pragma_align:
393 ProhibitAttributes(Attrs&: CXX11Attrs);
394 ProhibitAttributes(Attrs&: GNUAttrs);
395 HandlePragmaAlign();
396 return StmtEmpty();
397
398 case tok::annot_pragma_weak:
399 ProhibitAttributes(Attrs&: CXX11Attrs);
400 ProhibitAttributes(Attrs&: GNUAttrs);
401 HandlePragmaWeak();
402 return StmtEmpty();
403
404 case tok::annot_pragma_weakalias:
405 ProhibitAttributes(Attrs&: CXX11Attrs);
406 ProhibitAttributes(Attrs&: GNUAttrs);
407 HandlePragmaWeakAlias();
408 return StmtEmpty();
409
410 case tok::annot_pragma_redefine_extname:
411 ProhibitAttributes(Attrs&: CXX11Attrs);
412 ProhibitAttributes(Attrs&: GNUAttrs);
413 HandlePragmaRedefineExtname();
414 return StmtEmpty();
415
416 case tok::annot_pragma_fp_contract:
417 ProhibitAttributes(Attrs&: CXX11Attrs);
418 ProhibitAttributes(Attrs&: GNUAttrs);
419 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";
420 ConsumeAnnotationToken();
421 return StmtError();
422
423 case tok::annot_pragma_fp:
424 ProhibitAttributes(Attrs&: CXX11Attrs);
425 ProhibitAttributes(Attrs&: GNUAttrs);
426 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";
427 ConsumeAnnotationToken();
428 return StmtError();
429
430 case tok::annot_pragma_fenv_access:
431 case tok::annot_pragma_fenv_access_ms:
432 ProhibitAttributes(Attrs&: CXX11Attrs);
433 ProhibitAttributes(Attrs&: GNUAttrs);
434 Diag(Tok, diag::err_pragma_file_or_compound_scope)
435 << (Kind == tok::annot_pragma_fenv_access ? "STDC FENV_ACCESS"
436 : "fenv_access");
437 ConsumeAnnotationToken();
438 return StmtEmpty();
439
440 case tok::annot_pragma_fenv_round:
441 ProhibitAttributes(Attrs&: CXX11Attrs);
442 ProhibitAttributes(Attrs&: GNUAttrs);
443 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND";
444 ConsumeAnnotationToken();
445 return StmtError();
446
447 case tok::annot_pragma_cx_limited_range:
448 ProhibitAttributes(Attrs&: CXX11Attrs);
449 ProhibitAttributes(Attrs&: GNUAttrs);
450 Diag(Tok, diag::err_pragma_file_or_compound_scope)
451 << "STDC CX_LIMITED_RANGE";
452 ConsumeAnnotationToken();
453 return StmtError();
454
455 case tok::annot_pragma_float_control:
456 ProhibitAttributes(Attrs&: CXX11Attrs);
457 ProhibitAttributes(Attrs&: GNUAttrs);
458 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";
459 ConsumeAnnotationToken();
460 return StmtError();
461
462 case tok::annot_pragma_opencl_extension:
463 ProhibitAttributes(Attrs&: CXX11Attrs);
464 ProhibitAttributes(Attrs&: GNUAttrs);
465 HandlePragmaOpenCLExtension();
466 return StmtEmpty();
467
468 case tok::annot_pragma_captured:
469 ProhibitAttributes(Attrs&: CXX11Attrs);
470 ProhibitAttributes(Attrs&: GNUAttrs);
471 return HandlePragmaCaptured();
472
473 case tok::annot_pragma_openmp:
474 // Prohibit attributes that are not OpenMP attributes, but only before
475 // processing a #pragma omp clause.
476 ProhibitAttributes(Attrs&: CXX11Attrs);
477 ProhibitAttributes(Attrs&: GNUAttrs);
478 [[fallthrough]];
479 case tok::annot_attr_openmp:
480 // Do not prohibit attributes if they were OpenMP attributes.
481 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
482
483 case tok::annot_pragma_openacc:
484 return ParseOpenACCDirectiveStmt();
485
486 case tok::annot_pragma_ms_pointers_to_members:
487 ProhibitAttributes(Attrs&: CXX11Attrs);
488 ProhibitAttributes(Attrs&: GNUAttrs);
489 HandlePragmaMSPointersToMembers();
490 return StmtEmpty();
491
492 case tok::annot_pragma_ms_pragma:
493 ProhibitAttributes(Attrs&: CXX11Attrs);
494 ProhibitAttributes(Attrs&: GNUAttrs);
495 HandlePragmaMSPragma();
496 return StmtEmpty();
497
498 case tok::annot_pragma_ms_vtordisp:
499 ProhibitAttributes(Attrs&: CXX11Attrs);
500 ProhibitAttributes(Attrs&: GNUAttrs);
501 HandlePragmaMSVtorDisp();
502 return StmtEmpty();
503
504 case tok::annot_pragma_loop_hint:
505 ProhibitAttributes(Attrs&: CXX11Attrs);
506 ProhibitAttributes(Attrs&: GNUAttrs);
507 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs&: CXX11Attrs);
508
509 case tok::annot_pragma_dump:
510 HandlePragmaDump();
511 return StmtEmpty();
512
513 case tok::annot_pragma_attribute:
514 HandlePragmaAttribute();
515 return StmtEmpty();
516 }
517
518 // If we reached this code, the statement must end in a semicolon.
519 if (!TryConsumeToken(Expected: tok::semi) && !Res.isInvalid()) {
520 // If the result was valid, then we do want to diagnose this. Use
521 // ExpectAndConsume to emit the diagnostic, even though we know it won't
522 // succeed.
523 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
524 // Skip until we see a } or ;, but don't eat it.
525 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
526 }
527
528 return Res;
529}
530
531/// Parse an expression statement.
532StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
533 // If a case keyword is missing, this is where it should be inserted.
534 Token OldToken = Tok;
535
536 ExprStatementTokLoc = Tok.getLocation();
537
538 // expression[opt] ';'
539 ExprResult Expr(ParseExpression());
540 if (Expr.isInvalid()) {
541 // If the expression is invalid, skip ahead to the next semicolon or '}'.
542 // Not doing this opens us up to the possibility of infinite loops if
543 // ParseExpression does not consume any tokens.
544 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
545 if (Tok.is(K: tok::semi))
546 ConsumeToken();
547 return Actions.ActOnExprStmtError();
548 }
549
550 if (Tok.is(K: tok::colon) && getCurScope()->isSwitchScope() &&
551 Actions.CheckCaseExpression(E: Expr.get())) {
552 // If a constant expression is followed by a colon inside a switch block,
553 // suggest a missing case keyword.
554 Diag(OldToken, diag::err_expected_case_before_expression)
555 << FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
556
557 // Recover parsing as a case statement.
558 return ParseCaseStatement(StmtCtx, /*MissingCase=*/true, Expr);
559 }
560
561 Token *CurTok = nullptr;
562 // If the semicolon is missing at the end of REPL input, consider if
563 // we want to do value printing. Note this is only enabled in C++ mode
564 // since part of the implementation requires C++ language features.
565 // Note we shouldn't eat the token since the callback needs it.
566 if (Tok.is(K: tok::annot_repl_input_end) && Actions.getLangOpts().CPlusPlus)
567 CurTok = &Tok;
568 else
569 // Otherwise, eat the semicolon.
570 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
571
572 StmtResult R = handleExprStmt(E: Expr, StmtCtx);
573 if (CurTok && !R.isInvalid())
574 CurTok->setAnnotationValue(R.get());
575
576 return R;
577}
578
579/// ParseSEHTryBlockCommon
580///
581/// seh-try-block:
582/// '__try' compound-statement seh-handler
583///
584/// seh-handler:
585/// seh-except-block
586/// seh-finally-block
587///
588StmtResult Parser::ParseSEHTryBlock() {
589 assert(Tok.is(tok::kw___try) && "Expected '__try'");
590 SourceLocation TryLoc = ConsumeToken();
591
592 if (Tok.isNot(tok::l_brace))
593 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
594
595 StmtResult TryBlock(ParseCompoundStatement(
596 /*isStmtExpr=*/false,
597 ScopeFlags: Scope::DeclScope | Scope::CompoundStmtScope | Scope::SEHTryScope));
598 if (TryBlock.isInvalid())
599 return TryBlock;
600
601 StmtResult Handler;
602 if (Tok.is(K: tok::identifier) &&
603 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
604 SourceLocation Loc = ConsumeToken();
605 Handler = ParseSEHExceptBlock(Loc);
606 } else if (Tok.is(K: tok::kw___finally)) {
607 SourceLocation Loc = ConsumeToken();
608 Handler = ParseSEHFinallyBlock(Loc);
609 } else {
610 return StmtError(Diag(Tok, diag::err_seh_expected_handler));
611 }
612
613 if(Handler.isInvalid())
614 return Handler;
615
616 return Actions.ActOnSEHTryBlock(IsCXXTry: false /* IsCXXTry */,
617 TryLoc,
618 TryBlock: TryBlock.get(),
619 Handler: Handler.get());
620}
621
622/// ParseSEHExceptBlock - Handle __except
623///
624/// seh-except-block:
625/// '__except' '(' seh-filter-expression ')' compound-statement
626///
627StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
628 PoisonIdentifierRAIIObject raii(Ident__exception_code, false),
629 raii2(Ident___exception_code, false),
630 raii3(Ident_GetExceptionCode, false);
631
632 if (ExpectAndConsume(ExpectedTok: tok::l_paren))
633 return StmtError();
634
635 ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope |
636 Scope::SEHExceptScope);
637
638 if (getLangOpts().Borland) {
639 Ident__exception_info->setIsPoisoned(false);
640 Ident___exception_info->setIsPoisoned(false);
641 Ident_GetExceptionInfo->setIsPoisoned(false);
642 }
643
644 ExprResult FilterExpr;
645 {
646 ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |
647 Scope::SEHFilterScope);
648 FilterExpr = Actions.CorrectDelayedTyposInExpr(ER: ParseExpression());
649 }
650
651 if (getLangOpts().Borland) {
652 Ident__exception_info->setIsPoisoned(true);
653 Ident___exception_info->setIsPoisoned(true);
654 Ident_GetExceptionInfo->setIsPoisoned(true);
655 }
656
657 if(FilterExpr.isInvalid())
658 return StmtError();
659
660 if (ExpectAndConsume(ExpectedTok: tok::r_paren))
661 return StmtError();
662
663 if (Tok.isNot(tok::l_brace))
664 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
665
666 StmtResult Block(ParseCompoundStatement());
667
668 if(Block.isInvalid())
669 return Block;
670
671 return Actions.ActOnSEHExceptBlock(Loc: ExceptLoc, FilterExpr: FilterExpr.get(), Block: Block.get());
672}
673
674/// ParseSEHFinallyBlock - Handle __finally
675///
676/// seh-finally-block:
677/// '__finally' compound-statement
678///
679StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyLoc) {
680 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
681 raii2(Ident___abnormal_termination, false),
682 raii3(Ident_AbnormalTermination, false);
683
684 if (Tok.isNot(tok::l_brace))
685 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
686
687 ParseScope FinallyScope(this, 0);
688 Actions.ActOnStartSEHFinallyBlock();
689
690 StmtResult Block(ParseCompoundStatement());
691 if(Block.isInvalid()) {
692 Actions.ActOnAbortSEHFinallyBlock();
693 return Block;
694 }
695
696 return Actions.ActOnFinishSEHFinallyBlock(Loc: FinallyLoc, Block: Block.get());
697}
698
699/// Handle __leave
700///
701/// seh-leave-statement:
702/// '__leave' ';'
703///
704StmtResult Parser::ParseSEHLeaveStatement() {
705 SourceLocation LeaveLoc = ConsumeToken(); // eat the '__leave'.
706 return Actions.ActOnSEHLeaveStmt(Loc: LeaveLoc, CurScope: getCurScope());
707}
708
709static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt) {
710 // When in C mode (but not Microsoft extensions mode), diagnose use of a
711 // label that is followed by a declaration rather than a statement.
712 if (!P.getLangOpts().CPlusPlus && !P.getLangOpts().MicrosoftExt &&
713 isa<DeclStmt>(Val: SubStmt)) {
714 P.Diag(SubStmt->getBeginLoc(),
715 P.getLangOpts().C23
716 ? diag::warn_c23_compat_label_followed_by_declaration
717 : diag::ext_c_label_followed_by_declaration);
718 }
719}
720
721/// ParseLabeledStatement - We have an identifier and a ':' after it.
722///
723/// label:
724/// identifier ':'
725/// [GNU] identifier ':' attributes[opt]
726///
727/// labeled-statement:
728/// label statement
729///
730StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
731 ParsedStmtContext StmtCtx) {
732 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
733 "Not an identifier!");
734
735 // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a
736 // substatement in a selection statement, in place of the loop body in an
737 // iteration statement, or in place of the statement that follows a label.
738 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
739
740 Token IdentTok = Tok; // Save the whole token.
741 ConsumeToken(); // eat the identifier.
742
743 assert(Tok.is(tok::colon) && "Not a label!");
744
745 // identifier ':' statement
746 SourceLocation ColonLoc = ConsumeToken();
747
748 // Read label attributes, if present.
749 StmtResult SubStmt;
750 if (Tok.is(K: tok::kw___attribute)) {
751 ParsedAttributes TempAttrs(AttrFactory);
752 ParseGNUAttributes(Attrs&: TempAttrs);
753
754 // In C++, GNU attributes only apply to the label if they are followed by a
755 // semicolon, to disambiguate label attributes from attributes on a labeled
756 // declaration.
757 //
758 // This doesn't quite match what GCC does; if the attribute list is empty
759 // and followed by a semicolon, GCC will reject (it appears to parse the
760 // attributes as part of a statement in that case). That looks like a bug.
761 if (!getLangOpts().CPlusPlus || Tok.is(K: tok::semi))
762 Attrs.takeAllFrom(Other&: TempAttrs);
763 else {
764 StmtVector Stmts;
765 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
766 SubStmt = ParseStatementOrDeclarationAfterAttributes(
767 Stmts, StmtCtx, TrailingElseLoc: nullptr, CXX11Attrs&: EmptyCXX11Attrs, GNUAttrs&: TempAttrs);
768 if (!TempAttrs.empty() && !SubStmt.isInvalid())
769 SubStmt = Actions.ActOnAttributedStmt(AttrList: TempAttrs, SubStmt: SubStmt.get());
770 }
771 }
772
773 // The label may have no statement following it
774 if (SubStmt.isUnset() && Tok.is(K: tok::r_brace)) {
775 DiagnoseLabelAtEndOfCompoundStatement();
776 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
777 }
778
779 // If we've not parsed a statement yet, parse one now.
780 if (!SubStmt.isInvalid() && !SubStmt.isUsable())
781 SubStmt = ParseStatement(TrailingElseLoc: nullptr, StmtCtx);
782
783 // Broken substmt shouldn't prevent the label from being added to the AST.
784 if (SubStmt.isInvalid())
785 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
786
787 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
788
789 LabelDecl *LD = Actions.LookupOrCreateLabel(II: IdentTok.getIdentifierInfo(),
790 IdentLoc: IdentTok.getLocation());
791 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
792 Attrs.clear();
793
794 return Actions.ActOnLabelStmt(IdentLoc: IdentTok.getLocation(), TheDecl: LD, ColonLoc,
795 SubStmt: SubStmt.get());
796}
797
798/// ParseCaseStatement
799/// labeled-statement:
800/// 'case' constant-expression ':' statement
801/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
802///
803StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
804 bool MissingCase, ExprResult Expr) {
805 assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
806
807 // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a
808 // substatement in a selection statement, in place of the loop body in an
809 // iteration statement, or in place of the statement that follows a label.
810 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
811
812 // It is very common for code to contain many case statements recursively
813 // nested, as in (but usually without indentation):
814 // case 1:
815 // case 2:
816 // case 3:
817 // case 4:
818 // case 5: etc.
819 //
820 // Parsing this naively works, but is both inefficient and can cause us to run
821 // out of stack space in our recursive descent parser. As a special case,
822 // flatten this recursion into an iterative loop. This is complex and gross,
823 // but all the grossness is constrained to ParseCaseStatement (and some
824 // weirdness in the actions), so this is just local grossness :).
825
826 // TopLevelCase - This is the highest level we have parsed. 'case 1' in the
827 // example above.
828 StmtResult TopLevelCase(true);
829
830 // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
831 // gets updated each time a new case is parsed, and whose body is unset so
832 // far. When parsing 'case 4', this is the 'case 3' node.
833 Stmt *DeepestParsedCaseStmt = nullptr;
834
835 // While we have case statements, eat and stack them.
836 SourceLocation ColonLoc;
837 do {
838 SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :
839 ConsumeToken(); // eat the 'case'.
840 ColonLoc = SourceLocation();
841
842 if (Tok.is(K: tok::code_completion)) {
843 cutOffParsing();
844 Actions.CodeCompleteCase(S: getCurScope());
845 return StmtError();
846 }
847
848 /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
849 /// Disable this form of error recovery while we're parsing the case
850 /// expression.
851 ColonProtectionRAIIObject ColonProtection(*this);
852
853 ExprResult LHS;
854 if (!MissingCase) {
855 LHS = ParseCaseExpression(CaseLoc);
856 if (LHS.isInvalid()) {
857 // If constant-expression is parsed unsuccessfully, recover by skipping
858 // current case statement (moving to the colon that ends it).
859 if (!SkipUntil(T1: tok::colon, T2: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch))
860 return StmtError();
861 }
862 } else {
863 LHS = Expr;
864 MissingCase = false;
865 }
866
867 // GNU case range extension.
868 SourceLocation DotDotDotLoc;
869 ExprResult RHS;
870 if (TryConsumeToken(Expected: tok::ellipsis, Loc&: DotDotDotLoc)) {
871 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
872 RHS = ParseCaseExpression(CaseLoc);
873 if (RHS.isInvalid()) {
874 if (!SkipUntil(T1: tok::colon, T2: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch))
875 return StmtError();
876 }
877 }
878
879 ColonProtection.restore();
880
881 if (TryConsumeToken(Expected: tok::colon, Loc&: ColonLoc)) {
882 } else if (TryConsumeToken(Expected: tok::semi, Loc&: ColonLoc) ||
883 TryConsumeToken(Expected: tok::coloncolon, Loc&: ColonLoc)) {
884 // Treat "case blah;" or "case blah::" as a typo for "case blah:".
885 Diag(ColonLoc, diag::err_expected_after)
886 << "'case'" << tok::colon
887 << FixItHint::CreateReplacement(ColonLoc, ":");
888 } else {
889 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(Loc: PrevTokLocation);
890 Diag(ExpectedLoc, diag::err_expected_after)
891 << "'case'" << tok::colon
892 << FixItHint::CreateInsertion(ExpectedLoc, ":");
893 ColonLoc = ExpectedLoc;
894 }
895
896 StmtResult Case =
897 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
898
899 // If we had a sema error parsing this case, then just ignore it and
900 // continue parsing the sub-stmt.
901 if (Case.isInvalid()) {
902 if (TopLevelCase.isInvalid()) // No parsed case stmts.
903 return ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
904 // Otherwise, just don't add it as a nested case.
905 } else {
906 // If this is the first case statement we parsed, it becomes TopLevelCase.
907 // Otherwise we link it into the current chain.
908 Stmt *NextDeepest = Case.get();
909 if (TopLevelCase.isInvalid())
910 TopLevelCase = Case;
911 else
912 Actions.ActOnCaseStmtBody(CaseStmt: DeepestParsedCaseStmt, SubStmt: Case.get());
913 DeepestParsedCaseStmt = NextDeepest;
914 }
915
916 // Handle all case statements.
917 } while (Tok.is(K: tok::kw_case));
918
919 // If we found a non-case statement, start by parsing it.
920 StmtResult SubStmt;
921
922 if (Tok.is(K: tok::r_brace)) {
923 // "switch (X) { case 4: }", is valid and is treated as if label was
924 // followed by a null statement.
925 DiagnoseLabelAtEndOfCompoundStatement();
926 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
927 } else {
928 SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
929 }
930
931 // Install the body into the most deeply-nested case.
932 if (DeepestParsedCaseStmt) {
933 // Broken sub-stmt shouldn't prevent forming the case statement properly.
934 if (SubStmt.isInvalid())
935 SubStmt = Actions.ActOnNullStmt(SemiLoc: SourceLocation());
936 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
937 Actions.ActOnCaseStmtBody(CaseStmt: DeepestParsedCaseStmt, SubStmt: SubStmt.get());
938 }
939
940 // Return the top level parsed statement tree.
941 return TopLevelCase;
942}
943
944/// ParseDefaultStatement
945/// labeled-statement:
946/// 'default' ':' statement
947/// Note that this does not parse the 'statement' at the end.
948///
949StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
950 assert(Tok.is(tok::kw_default) && "Not a default stmt!");
951
952 // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a
953 // substatement in a selection statement, in place of the loop body in an
954 // iteration statement, or in place of the statement that follows a label.
955 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
956
957 SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
958
959 SourceLocation ColonLoc;
960 if (TryConsumeToken(Expected: tok::colon, Loc&: ColonLoc)) {
961 } else if (TryConsumeToken(Expected: tok::semi, Loc&: ColonLoc)) {
962 // Treat "default;" as a typo for "default:".
963 Diag(ColonLoc, diag::err_expected_after)
964 << "'default'" << tok::colon
965 << FixItHint::CreateReplacement(ColonLoc, ":");
966 } else {
967 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(Loc: PrevTokLocation);
968 Diag(ExpectedLoc, diag::err_expected_after)
969 << "'default'" << tok::colon
970 << FixItHint::CreateInsertion(ExpectedLoc, ":");
971 ColonLoc = ExpectedLoc;
972 }
973
974 StmtResult SubStmt;
975
976 if (Tok.is(K: tok::r_brace)) {
977 // "switch (X) {... default: }", is valid and is treated as if label was
978 // followed by a null statement.
979 DiagnoseLabelAtEndOfCompoundStatement();
980 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
981 } else {
982 SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
983 }
984
985 // Broken sub-stmt shouldn't prevent forming the case statement properly.
986 if (SubStmt.isInvalid())
987 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
988
989 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
990 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
991 SubStmt: SubStmt.get(), CurScope: getCurScope());
992}
993
994StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
995 return ParseCompoundStatement(isStmtExpr,
996 ScopeFlags: Scope::DeclScope | Scope::CompoundStmtScope);
997}
998
999/// ParseCompoundStatement - Parse a "{}" block.
1000///
1001/// compound-statement: [C99 6.8.2]
1002/// { block-item-list[opt] }
1003/// [GNU] { label-declarations block-item-list } [TODO]
1004///
1005/// block-item-list:
1006/// block-item
1007/// block-item-list block-item
1008///
1009/// block-item:
1010/// declaration
1011/// [GNU] '__extension__' declaration
1012/// statement
1013///
1014/// [GNU] label-declarations:
1015/// [GNU] label-declaration
1016/// [GNU] label-declarations label-declaration
1017///
1018/// [GNU] label-declaration:
1019/// [GNU] '__label__' identifier-list ';'
1020///
1021StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
1022 unsigned ScopeFlags) {
1023 assert(Tok.is(tok::l_brace) && "Not a compound stmt!");
1024
1025 // Enter a scope to hold everything within the compound stmt. Compound
1026 // statements can always hold declarations.
1027 ParseScope CompoundScope(this, ScopeFlags);
1028
1029 // Parse the statements in the body.
1030 return ParseCompoundStatementBody(isStmtExpr);
1031}
1032
1033/// Parse any pragmas at the start of the compound expression. We handle these
1034/// separately since some pragmas (FP_CONTRACT) must appear before any C
1035/// statement in the compound, but may be intermingled with other pragmas.
1036void Parser::ParseCompoundStatementLeadingPragmas() {
1037 bool checkForPragmas = true;
1038 while (checkForPragmas) {
1039 switch (Tok.getKind()) {
1040 case tok::annot_pragma_vis:
1041 HandlePragmaVisibility();
1042 break;
1043 case tok::annot_pragma_pack:
1044 HandlePragmaPack();
1045 break;
1046 case tok::annot_pragma_msstruct:
1047 HandlePragmaMSStruct();
1048 break;
1049 case tok::annot_pragma_align:
1050 HandlePragmaAlign();
1051 break;
1052 case tok::annot_pragma_weak:
1053 HandlePragmaWeak();
1054 break;
1055 case tok::annot_pragma_weakalias:
1056 HandlePragmaWeakAlias();
1057 break;
1058 case tok::annot_pragma_redefine_extname:
1059 HandlePragmaRedefineExtname();
1060 break;
1061 case tok::annot_pragma_opencl_extension:
1062 HandlePragmaOpenCLExtension();
1063 break;
1064 case tok::annot_pragma_fp_contract:
1065 HandlePragmaFPContract();
1066 break;
1067 case tok::annot_pragma_fp:
1068 HandlePragmaFP();
1069 break;
1070 case tok::annot_pragma_fenv_access:
1071 case tok::annot_pragma_fenv_access_ms:
1072 HandlePragmaFEnvAccess();
1073 break;
1074 case tok::annot_pragma_fenv_round:
1075 HandlePragmaFEnvRound();
1076 break;
1077 case tok::annot_pragma_cx_limited_range:
1078 HandlePragmaCXLimitedRange();
1079 break;
1080 case tok::annot_pragma_float_control:
1081 HandlePragmaFloatControl();
1082 break;
1083 case tok::annot_pragma_ms_pointers_to_members:
1084 HandlePragmaMSPointersToMembers();
1085 break;
1086 case tok::annot_pragma_ms_pragma:
1087 HandlePragmaMSPragma();
1088 break;
1089 case tok::annot_pragma_ms_vtordisp:
1090 HandlePragmaMSVtorDisp();
1091 break;
1092 case tok::annot_pragma_dump:
1093 HandlePragmaDump();
1094 break;
1095 default:
1096 checkForPragmas = false;
1097 break;
1098 }
1099 }
1100
1101}
1102
1103void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1104 if (getLangOpts().CPlusPlus) {
1105 Diag(Tok, getLangOpts().CPlusPlus23
1106 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1107 : diag::ext_cxx_label_end_of_compound_statement);
1108 } else {
1109 Diag(Tok, getLangOpts().C23
1110 ? diag::warn_c23_compat_label_end_of_compound_statement
1111 : diag::ext_c_label_end_of_compound_statement);
1112 }
1113}
1114
1115/// Consume any extra semi-colons resulting in null statements,
1116/// returning true if any tok::semi were consumed.
1117bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1118 if (!Tok.is(K: tok::semi))
1119 return false;
1120
1121 SourceLocation StartLoc = Tok.getLocation();
1122 SourceLocation EndLoc;
1123
1124 while (Tok.is(K: tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1125 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1126 EndLoc = Tok.getLocation();
1127
1128 // Don't just ConsumeToken() this tok::semi, do store it in AST.
1129 StmtResult R =
1130 ParseStatementOrDeclaration(Stmts, StmtCtx: ParsedStmtContext::SubStmt);
1131 if (R.isUsable())
1132 Stmts.push_back(Elt: R.get());
1133 }
1134
1135 // Did not consume any extra semi.
1136 if (EndLoc.isInvalid())
1137 return false;
1138
1139 Diag(StartLoc, diag::warn_null_statement)
1140 << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
1141 return true;
1142}
1143
1144StmtResult Parser::handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx) {
1145 bool IsStmtExprResult = false;
1146 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1147 // For GCC compatibility we skip past NullStmts.
1148 unsigned LookAhead = 0;
1149 while (GetLookAheadToken(N: LookAhead).is(K: tok::semi)) {
1150 ++LookAhead;
1151 }
1152 // Then look to see if the next two tokens close the statement expression;
1153 // if so, this expression statement is the last statement in a statement
1154 // expression.
1155 IsStmtExprResult = GetLookAheadToken(N: LookAhead).is(K: tok::r_brace) &&
1156 GetLookAheadToken(N: LookAhead + 1).is(K: tok::r_paren);
1157 }
1158
1159 if (IsStmtExprResult)
1160 E = Actions.ActOnStmtExprResult(E);
1161 return Actions.ActOnExprStmt(Arg: E, /*DiscardedValue=*/!IsStmtExprResult);
1162}
1163
1164/// ParseCompoundStatementBody - Parse a sequence of statements optionally
1165/// followed by a label and invoke the ActOnCompoundStmt action. This expects
1166/// the '{' to be the current token, and consume the '}' at the end of the
1167/// block. It does not manipulate the scope stack.
1168StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
1169 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1170 Tok.getLocation(),
1171 "in compound statement ('{}')");
1172
1173 // Record the current FPFeatures, restore on leaving the
1174 // compound statement.
1175 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1176
1177 InMessageExpressionRAIIObject InMessage(*this, false);
1178 BalancedDelimiterTracker T(*this, tok::l_brace);
1179 if (T.consumeOpen())
1180 return StmtError();
1181
1182 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1183
1184 // Parse any pragmas at the beginning of the compound statement.
1185 ParseCompoundStatementLeadingPragmas();
1186 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1187
1188 StmtVector Stmts;
1189
1190 // "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are
1191 // only allowed at the start of a compound stmt regardless of the language.
1192 while (Tok.is(K: tok::kw___label__)) {
1193 SourceLocation LabelLoc = ConsumeToken();
1194
1195 SmallVector<Decl *, 8> DeclsInGroup;
1196 while (true) {
1197 if (Tok.isNot(K: tok::identifier)) {
1198 Diag(Tok, diag::err_expected) << tok::identifier;
1199 break;
1200 }
1201
1202 IdentifierInfo *II = Tok.getIdentifierInfo();
1203 SourceLocation IdLoc = ConsumeToken();
1204 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdentLoc: IdLoc, GnuLabelLoc: LabelLoc));
1205
1206 if (!TryConsumeToken(Expected: tok::comma))
1207 break;
1208 }
1209
1210 DeclSpec DS(AttrFactory);
1211 DeclGroupPtrTy Res =
1212 Actions.FinalizeDeclaratorGroup(S: getCurScope(), DS, Group: DeclsInGroup);
1213 StmtResult R = Actions.ActOnDeclStmt(Decl: Res, StartLoc: LabelLoc, EndLoc: Tok.getLocation());
1214
1215 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1216 if (R.isUsable())
1217 Stmts.push_back(Elt: R.get());
1218 }
1219
1220 ParsedStmtContext SubStmtCtx =
1221 ParsedStmtContext::Compound |
1222 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1223
1224 while (!tryParseMisplacedModuleImport() && Tok.isNot(K: tok::r_brace) &&
1225 Tok.isNot(K: tok::eof)) {
1226 if (Tok.is(K: tok::annot_pragma_unused)) {
1227 HandlePragmaUnused();
1228 continue;
1229 }
1230
1231 if (ConsumeNullStmt(Stmts))
1232 continue;
1233
1234 StmtResult R;
1235 if (Tok.isNot(K: tok::kw___extension__)) {
1236 R = ParseStatementOrDeclaration(Stmts, StmtCtx: SubStmtCtx);
1237 } else {
1238 // __extension__ can start declarations and it can also be a unary
1239 // operator for expressions. Consume multiple __extension__ markers here
1240 // until we can determine which is which.
1241 // FIXME: This loses extension expressions in the AST!
1242 SourceLocation ExtLoc = ConsumeToken();
1243 while (Tok.is(K: tok::kw___extension__))
1244 ConsumeToken();
1245
1246 ParsedAttributes attrs(AttrFactory);
1247 MaybeParseCXX11Attributes(Attrs&: attrs, /*MightBeObjCMessageSend*/ OuterMightBeMessageSend: true);
1248
1249 // If this is the start of a declaration, parse it as such.
1250 if (isDeclarationStatement()) {
1251 // __extension__ silences extension warnings in the subdeclaration.
1252 // FIXME: Save the __extension__ on the decl as a node somehow?
1253 ExtensionRAIIObject O(Diags);
1254
1255 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1256 ParsedAttributes DeclSpecAttrs(AttrFactory);
1257 DeclGroupPtrTy Res = ParseDeclaration(Context: DeclaratorContext::Block, DeclEnd,
1258 DeclAttrs&: attrs, DeclSpecAttrs);
1259 R = Actions.ActOnDeclStmt(Decl: Res, StartLoc: DeclStart, EndLoc: DeclEnd);
1260 } else {
1261 // Otherwise this was a unary __extension__ marker.
1262 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1263
1264 if (Res.isInvalid()) {
1265 SkipUntil(T: tok::semi);
1266 continue;
1267 }
1268
1269 // Eat the semicolon at the end of stmt and convert the expr into a
1270 // statement.
1271 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1272 R = handleExprStmt(E: Res, StmtCtx: SubStmtCtx);
1273 if (R.isUsable())
1274 R = Actions.ActOnAttributedStmt(AttrList: attrs, SubStmt: R.get());
1275 }
1276 }
1277
1278 if (R.isUsable())
1279 Stmts.push_back(Elt: R.get());
1280 }
1281 // Warn the user that using option `-ffp-eval-method=source` on a
1282 // 32-bit target and feature `sse` disabled, or using
1283 // `pragma clang fp eval_method=source` and feature `sse` disabled, is not
1284 // supported.
1285 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1286 (PP.getLastFPEvalPragmaLocation().isValid() ||
1287 PP.getCurrentFPEvalMethod() ==
1288 LangOptions::FPEvalMethodKind::FEM_Source))
1289 Diag(Tok.getLocation(),
1290 diag::warn_no_support_for_eval_method_source_on_m32);
1291
1292 SourceLocation CloseLoc = Tok.getLocation();
1293
1294 // We broke out of the while loop because we found a '}' or EOF.
1295 if (!T.consumeClose()) {
1296 // If this is the '})' of a statement expression, check that it's written
1297 // in a sensible way.
1298 if (isStmtExpr && Tok.is(K: tok::r_paren))
1299 checkCompoundToken(FirstTokLoc: CloseLoc, FirstTokKind: tok::r_brace, Op: CompoundToken::StmtExprEnd);
1300 } else {
1301 // Recover by creating a compound statement with what we parsed so far,
1302 // instead of dropping everything and returning StmtError().
1303 }
1304
1305 if (T.getCloseLocation().isValid())
1306 CloseLoc = T.getCloseLocation();
1307
1308 return Actions.ActOnCompoundStmt(L: T.getOpenLocation(), R: CloseLoc,
1309 Elts: Stmts, isStmtExpr);
1310}
1311
1312/// ParseParenExprOrCondition:
1313/// [C ] '(' expression ')'
1314/// [C++] '(' condition ')'
1315/// [C++1z] '(' init-statement[opt] condition ')'
1316///
1317/// This function parses and performs error recovery on the specified condition
1318/// or expression (depending on whether we're in C++ or C mode). This function
1319/// goes out of its way to recover well. It returns true if there was a parser
1320/// error (the right paren couldn't be found), which indicates that the caller
1321/// should try to recover harder. It returns false if the condition is
1322/// successfully parsed. Note that a successful parse can still have semantic
1323/// errors in the condition.
1324/// Additionally, it will assign the location of the outer-most '(' and ')',
1325/// to LParenLoc and RParenLoc, respectively.
1326bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
1327 Sema::ConditionResult &Cond,
1328 SourceLocation Loc,
1329 Sema::ConditionKind CK,
1330 SourceLocation &LParenLoc,
1331 SourceLocation &RParenLoc) {
1332 BalancedDelimiterTracker T(*this, tok::l_paren);
1333 T.consumeOpen();
1334 SourceLocation Start = Tok.getLocation();
1335
1336 if (getLangOpts().CPlusPlus) {
1337 Cond = ParseCXXCondition(InitStmt, Loc, CK, MissingOK: false);
1338 } else {
1339 ExprResult CondExpr = ParseExpression();
1340
1341 // If required, convert to a boolean value.
1342 if (CondExpr.isInvalid())
1343 Cond = Sema::ConditionError();
1344 else
1345 Cond = Actions.ActOnCondition(S: getCurScope(), Loc, SubExpr: CondExpr.get(), CK,
1346 /*MissingOK=*/false);
1347 }
1348
1349 // If the parser was confused by the condition and we don't have a ')', try to
1350 // recover by skipping ahead to a semi and bailing out. If condexp is
1351 // semantically invalid but we have well formed code, keep going.
1352 if (Cond.isInvalid() && Tok.isNot(K: tok::r_paren)) {
1353 SkipUntil(T: tok::semi);
1354 // Skipping may have stopped if it found the containing ')'. If so, we can
1355 // continue parsing the if statement.
1356 if (Tok.isNot(K: tok::r_paren))
1357 return true;
1358 }
1359
1360 if (Cond.isInvalid()) {
1361 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1362 Begin: Start, End: Tok.getLocation() == Start ? Start : PrevTokLocation, SubExprs: {},
1363 T: Actions.PreferredConditionType(K: CK));
1364 if (!CondExpr.isInvalid())
1365 Cond = Actions.ActOnCondition(S: getCurScope(), Loc, SubExpr: CondExpr.get(), CK,
1366 /*MissingOK=*/false);
1367 }
1368
1369 // Either the condition is valid or the rparen is present.
1370 T.consumeClose();
1371 LParenLoc = T.getOpenLocation();
1372 RParenLoc = T.getCloseLocation();
1373
1374 // Check for extraneous ')'s to catch things like "if (foo())) {". We know
1375 // that all callers are looking for a statement after the condition, so ")"
1376 // isn't valid.
1377 while (Tok.is(K: tok::r_paren)) {
1378 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1379 << FixItHint::CreateRemoval(Tok.getLocation());
1380 ConsumeParen();
1381 }
1382
1383 return false;
1384}
1385
1386namespace {
1387
1388enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1389
1390struct MisleadingIndentationChecker {
1391 Parser &P;
1392 SourceLocation StmtLoc;
1393 SourceLocation PrevLoc;
1394 unsigned NumDirectives;
1395 MisleadingStatementKind Kind;
1396 bool ShouldSkip;
1397 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1398 SourceLocation SL)
1399 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1400 NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
1401 ShouldSkip(P.getCurToken().is(K: tok::l_brace)) {
1402 if (!P.MisleadingIndentationElseLoc.isInvalid()) {
1403 StmtLoc = P.MisleadingIndentationElseLoc;
1404 P.MisleadingIndentationElseLoc = SourceLocation();
1405 }
1406 if (Kind == MSK_else && !ShouldSkip)
1407 P.MisleadingIndentationElseLoc = SL;
1408 }
1409
1410 /// Compute the column number will aligning tabs on TabStop (-ftabstop), this
1411 /// gives the visual indentation of the SourceLocation.
1412 static unsigned getVisualIndentation(SourceManager &SM, SourceLocation Loc) {
1413 unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
1414
1415 unsigned ColNo = SM.getSpellingColumnNumber(Loc);
1416 if (ColNo == 0 || TabStop == 1)
1417 return ColNo;
1418
1419 std::pair<FileID, unsigned> FIDAndOffset = SM.getDecomposedLoc(Loc);
1420
1421 bool Invalid;
1422 StringRef BufData = SM.getBufferData(FID: FIDAndOffset.first, Invalid: &Invalid);
1423 if (Invalid)
1424 return 0;
1425
1426 const char *EndPos = BufData.data() + FIDAndOffset.second;
1427 // FileOffset are 0-based and Column numbers are 1-based
1428 assert(FIDAndOffset.second + 1 >= ColNo &&
1429 "Column number smaller than file offset?");
1430
1431 unsigned VisualColumn = 0; // Stored as 0-based column, here.
1432 // Loop from beginning of line up to Loc's file position, counting columns,
1433 // expanding tabs.
1434 for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1435 ++CurPos) {
1436 if (*CurPos == '\t')
1437 // Advance visual column to next tabstop.
1438 VisualColumn += (TabStop - VisualColumn % TabStop);
1439 else
1440 VisualColumn++;
1441 }
1442 return VisualColumn + 1;
1443 }
1444
1445 void Check() {
1446 Token Tok = P.getCurToken();
1447 if (P.getActions().getDiagnostics().isIgnored(
1448 diag::warn_misleading_indentation, Tok.getLocation()) ||
1449 ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||
1450 Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||
1451 Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||
1452 StmtLoc.isMacroID() ||
1453 (Kind == MSK_else && P.MisleadingIndentationElseLoc.isInvalid())) {
1454 P.MisleadingIndentationElseLoc = SourceLocation();
1455 return;
1456 }
1457 if (Kind == MSK_else)
1458 P.MisleadingIndentationElseLoc = SourceLocation();
1459
1460 SourceManager &SM = P.getPreprocessor().getSourceManager();
1461 unsigned PrevColNum = getVisualIndentation(SM, Loc: PrevLoc);
1462 unsigned CurColNum = getVisualIndentation(SM, Loc: Tok.getLocation());
1463 unsigned StmtColNum = getVisualIndentation(SM, Loc: StmtLoc);
1464
1465 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1466 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1467 !Tok.isAtStartOfLine()) &&
1468 SM.getPresumedLineNumber(Loc: StmtLoc) !=
1469 SM.getPresumedLineNumber(Loc: Tok.getLocation()) &&
1470 (Tok.isNot(K: tok::identifier) ||
1471 P.getPreprocessor().LookAhead(N: 0).isNot(K: tok::colon))) {
1472 P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
1473 P.Diag(StmtLoc, diag::note_previous_statement);
1474 }
1475 }
1476};
1477
1478}
1479
1480/// ParseIfStatement
1481/// if-statement: [C99 6.8.4.1]
1482/// 'if' '(' expression ')' statement
1483/// 'if' '(' expression ')' statement 'else' statement
1484/// [C++] 'if' '(' condition ')' statement
1485/// [C++] 'if' '(' condition ')' statement 'else' statement
1486/// [C++23] 'if' '!' [opt] consteval compound-statement
1487/// [C++23] 'if' '!' [opt] consteval compound-statement 'else' statement
1488///
1489StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
1490 assert(Tok.is(tok::kw_if) && "Not an if stmt!");
1491 SourceLocation IfLoc = ConsumeToken(); // eat the 'if'.
1492
1493 bool IsConstexpr = false;
1494 bool IsConsteval = false;
1495 SourceLocation NotLocation;
1496 SourceLocation ConstevalLoc;
1497
1498 if (Tok.is(K: tok::kw_constexpr)) {
1499 Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
1500 : diag::ext_constexpr_if);
1501 IsConstexpr = true;
1502 ConsumeToken();
1503 } else {
1504 if (Tok.is(K: tok::exclaim)) {
1505 NotLocation = ConsumeToken();
1506 }
1507
1508 if (Tok.is(K: tok::kw_consteval)) {
1509 Diag(Tok, getLangOpts().CPlusPlus23 ? diag::warn_cxx20_compat_consteval_if
1510 : diag::ext_consteval_if);
1511 IsConsteval = true;
1512 ConstevalLoc = ConsumeToken();
1513 }
1514 }
1515 if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(K: tok::l_paren))) {
1516 Diag(Tok, diag::err_expected_lparen_after) << "if";
1517 SkipUntil(T: tok::semi);
1518 return StmtError();
1519 }
1520
1521 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1522
1523 // C99 6.8.4p3 - In C99, the if statement is a block. This is not
1524 // the case for C90.
1525 //
1526 // C++ 6.4p3:
1527 // A name introduced by a declaration in a condition is in scope from its
1528 // point of declaration until the end of the substatements controlled by the
1529 // condition.
1530 // C++ 3.3.2p4:
1531 // Names declared in the for-init-statement, and in the condition of if,
1532 // while, for, and switch statements are local to the if, while, for, or
1533 // switch statement (including the controlled statement).
1534 //
1535 ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
1536
1537 // Parse the condition.
1538 StmtResult InitStmt;
1539 Sema::ConditionResult Cond;
1540 SourceLocation LParen;
1541 SourceLocation RParen;
1542 std::optional<bool> ConstexprCondition;
1543 if (!IsConsteval) {
1544
1545 if (ParseParenExprOrCondition(InitStmt: &InitStmt, Cond, Loc: IfLoc,
1546 CK: IsConstexpr ? Sema::ConditionKind::ConstexprIf
1547 : Sema::ConditionKind::Boolean,
1548 LParenLoc&: LParen, RParenLoc&: RParen))
1549 return StmtError();
1550
1551 if (IsConstexpr)
1552 ConstexprCondition = Cond.getKnownValue();
1553 }
1554
1555 bool IsBracedThen = Tok.is(K: tok::l_brace);
1556
1557 // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
1558 // there is no compound stmt. C90 does not have this clause. We only do this
1559 // if the body isn't a compound statement to avoid push/pop in common cases.
1560 //
1561 // C++ 6.4p1:
1562 // The substatement in a selection-statement (each substatement, in the else
1563 // form of the if statement) implicitly defines a local scope.
1564 //
1565 // For C++ we create a scope for the condition and a new scope for
1566 // substatements because:
1567 // -When the 'then' scope exits, we want the condition declaration to still be
1568 // active for the 'else' scope too.
1569 // -Sema will detect name clashes by considering declarations of a
1570 // 'ControlScope' as part of its direct subscope.
1571 // -If we wanted the condition and substatement to be in the same scope, we
1572 // would have to notify ParseStatement not to create a new scope. It's
1573 // simpler to let it create a new scope.
1574 //
1575 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
1576
1577 MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
1578
1579 // Read the 'then' stmt.
1580 SourceLocation ThenStmtLoc = Tok.getLocation();
1581
1582 SourceLocation InnerStatementTrailingElseLoc;
1583 StmtResult ThenStmt;
1584 {
1585 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1586 Sema::ExpressionEvaluationContext Context =
1587 Sema::ExpressionEvaluationContext::DiscardedStatement;
1588 if (NotLocation.isInvalid() && IsConsteval) {
1589 Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
1590 ShouldEnter = true;
1591 }
1592
1593 EnterExpressionEvaluationContext PotentiallyDiscarded(
1594 Actions, Context, nullptr,
1595 Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
1596 ThenStmt = ParseStatement(TrailingElseLoc: &InnerStatementTrailingElseLoc);
1597 }
1598
1599 if (Tok.isNot(K: tok::kw_else))
1600 MIChecker.Check();
1601
1602 // Pop the 'if' scope if needed.
1603 InnerScope.Exit();
1604
1605 // If it has an else, parse it.
1606 SourceLocation ElseLoc;
1607 SourceLocation ElseStmtLoc;
1608 StmtResult ElseStmt;
1609
1610 if (Tok.is(K: tok::kw_else)) {
1611 if (TrailingElseLoc)
1612 *TrailingElseLoc = Tok.getLocation();
1613
1614 ElseLoc = ConsumeToken();
1615 ElseStmtLoc = Tok.getLocation();
1616
1617 // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
1618 // there is no compound stmt. C90 does not have this clause. We only do
1619 // this if the body isn't a compound statement to avoid push/pop in common
1620 // cases.
1621 //
1622 // C++ 6.4p1:
1623 // The substatement in a selection-statement (each substatement, in the else
1624 // form of the if statement) implicitly defines a local scope.
1625 //
1626 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX,
1627 Tok.is(K: tok::l_brace));
1628
1629 MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);
1630 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1631 Sema::ExpressionEvaluationContext Context =
1632 Sema::ExpressionEvaluationContext::DiscardedStatement;
1633 if (NotLocation.isValid() && IsConsteval) {
1634 Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
1635 ShouldEnter = true;
1636 }
1637
1638 EnterExpressionEvaluationContext PotentiallyDiscarded(
1639 Actions, Context, nullptr,
1640 Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
1641 ElseStmt = ParseStatement();
1642
1643 if (ElseStmt.isUsable())
1644 MIChecker.Check();
1645
1646 // Pop the 'else' scope if needed.
1647 InnerScope.Exit();
1648 } else if (Tok.is(K: tok::code_completion)) {
1649 cutOffParsing();
1650 Actions.CodeCompleteAfterIf(S: getCurScope(), IsBracedThen);
1651 return StmtError();
1652 } else if (InnerStatementTrailingElseLoc.isValid()) {
1653 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1654 }
1655
1656 IfScope.Exit();
1657
1658 // If the then or else stmt is invalid and the other is valid (and present),
1659 // turn the invalid one into a null stmt to avoid dropping the other
1660 // part. If both are invalid, return error.
1661 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1662 (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
1663 (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
1664 // Both invalid, or one is invalid and other is non-present: return error.
1665 return StmtError();
1666 }
1667
1668 if (IsConsteval) {
1669 auto IsCompoundStatement = [](const Stmt *S) {
1670 if (const auto *Outer = dyn_cast_if_present<AttributedStmt>(Val: S))
1671 S = Outer->getSubStmt();
1672 return isa_and_nonnull<clang::CompoundStmt>(Val: S);
1673 };
1674
1675 if (!IsCompoundStatement(ThenStmt.get())) {
1676 Diag(ConstevalLoc, diag::err_expected_after) << "consteval"
1677 << "{";
1678 return StmtError();
1679 }
1680 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1681 Diag(ElseLoc, diag::err_expected_after) << "else"
1682 << "{";
1683 return StmtError();
1684 }
1685 }
1686
1687 // Now if either are invalid, replace with a ';'.
1688 if (ThenStmt.isInvalid())
1689 ThenStmt = Actions.ActOnNullStmt(SemiLoc: ThenStmtLoc);
1690 if (ElseStmt.isInvalid())
1691 ElseStmt = Actions.ActOnNullStmt(SemiLoc: ElseStmtLoc);
1692
1693 IfStatementKind Kind = IfStatementKind::Ordinary;
1694 if (IsConstexpr)
1695 Kind = IfStatementKind::Constexpr;
1696 else if (IsConsteval)
1697 Kind = NotLocation.isValid() ? IfStatementKind::ConstevalNegated
1698 : IfStatementKind::ConstevalNonNegated;
1699
1700 return Actions.ActOnIfStmt(IfLoc, StatementKind: Kind, LParenLoc: LParen, InitStmt: InitStmt.get(), Cond, RParenLoc: RParen,
1701 ThenVal: ThenStmt.get(), ElseLoc, ElseVal: ElseStmt.get());
1702}
1703
1704/// ParseSwitchStatement
1705/// switch-statement:
1706/// 'switch' '(' expression ')' statement
1707/// [C++] 'switch' '(' condition ')' statement
1708StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
1709 assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
1710 SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
1711
1712 if (Tok.isNot(K: tok::l_paren)) {
1713 Diag(Tok, diag::err_expected_lparen_after) << "switch";
1714 SkipUntil(T: tok::semi);
1715 return StmtError();
1716 }
1717
1718 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1719
1720 // C99 6.8.4p3 - In C99, the switch statement is a block. This is
1721 // not the case for C90. Start the switch scope.
1722 //
1723 // C++ 6.4p3:
1724 // A name introduced by a declaration in a condition is in scope from its
1725 // point of declaration until the end of the substatements controlled by the
1726 // condition.
1727 // C++ 3.3.2p4:
1728 // Names declared in the for-init-statement, and in the condition of if,
1729 // while, for, and switch statements are local to the if, while, for, or
1730 // switch statement (including the controlled statement).
1731 //
1732 unsigned ScopeFlags = Scope::SwitchScope;
1733 if (C99orCXX)
1734 ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
1735 ParseScope SwitchScope(this, ScopeFlags);
1736
1737 // Parse the condition.
1738 StmtResult InitStmt;
1739 Sema::ConditionResult Cond;
1740 SourceLocation LParen;
1741 SourceLocation RParen;
1742 if (ParseParenExprOrCondition(InitStmt: &InitStmt, Cond, Loc: SwitchLoc,
1743 CK: Sema::ConditionKind::Switch, LParenLoc&: LParen, RParenLoc&: RParen))
1744 return StmtError();
1745
1746 StmtResult Switch = Actions.ActOnStartOfSwitchStmt(
1747 SwitchLoc, LParenLoc: LParen, InitStmt: InitStmt.get(), Cond, RParenLoc: RParen);
1748
1749 if (Switch.isInvalid()) {
1750 // Skip the switch body.
1751 // FIXME: This is not optimal recovery, but parsing the body is more
1752 // dangerous due to the presence of case and default statements, which
1753 // will have no place to connect back with the switch.
1754 if (Tok.is(K: tok::l_brace)) {
1755 ConsumeBrace();
1756 SkipUntil(T: tok::r_brace);
1757 } else
1758 SkipUntil(T: tok::semi);
1759 return Switch;
1760 }
1761
1762 // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
1763 // there is no compound stmt. C90 does not have this clause. We only do this
1764 // if the body isn't a compound statement to avoid push/pop in common cases.
1765 //
1766 // C++ 6.4p1:
1767 // The substatement in a selection-statement (each substatement, in the else
1768 // form of the if statement) implicitly defines a local scope.
1769 //
1770 // See comments in ParseIfStatement for why we create a scope for the
1771 // condition and a new scope for substatement in C++.
1772 //
1773 getCurScope()->AddFlags(Flags: Scope::BreakScope);
1774 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1775
1776 // We have incremented the mangling number for the SwitchScope and the
1777 // InnerScope, which is one too many.
1778 if (C99orCXX)
1779 getCurScope()->decrementMSManglingNumber();
1780
1781 // Read the body statement.
1782 StmtResult Body(ParseStatement(TrailingElseLoc));
1783
1784 // Pop the scopes.
1785 InnerScope.Exit();
1786 SwitchScope.Exit();
1787
1788 return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch: Switch.get(), Body: Body.get());
1789}
1790
1791/// ParseWhileStatement
1792/// while-statement: [C99 6.8.5.1]
1793/// 'while' '(' expression ')' statement
1794/// [C++] 'while' '(' condition ')' statement
1795StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
1796 assert(Tok.is(tok::kw_while) && "Not a while stmt!");
1797 SourceLocation WhileLoc = Tok.getLocation();
1798 ConsumeToken(); // eat the 'while'.
1799
1800 if (Tok.isNot(K: tok::l_paren)) {
1801 Diag(Tok, diag::err_expected_lparen_after) << "while";
1802 SkipUntil(T: tok::semi);
1803 return StmtError();
1804 }
1805
1806 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1807
1808 // C99 6.8.5p5 - In C99, the while statement is a block. This is not
1809 // the case for C90. Start the loop scope.
1810 //
1811 // C++ 6.4p3:
1812 // A name introduced by a declaration in a condition is in scope from its
1813 // point of declaration until the end of the substatements controlled by the
1814 // condition.
1815 // C++ 3.3.2p4:
1816 // Names declared in the for-init-statement, and in the condition of if,
1817 // while, for, and switch statements are local to the if, while, for, or
1818 // switch statement (including the controlled statement).
1819 //
1820 unsigned ScopeFlags;
1821 if (C99orCXX)
1822 ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
1823 Scope::DeclScope | Scope::ControlScope;
1824 else
1825 ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
1826 ParseScope WhileScope(this, ScopeFlags);
1827
1828 // Parse the condition.
1829 Sema::ConditionResult Cond;
1830 SourceLocation LParen;
1831 SourceLocation RParen;
1832 if (ParseParenExprOrCondition(InitStmt: nullptr, Cond, Loc: WhileLoc,
1833 CK: Sema::ConditionKind::Boolean, LParenLoc&: LParen, RParenLoc&: RParen))
1834 return StmtError();
1835
1836 // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
1837 // there is no compound stmt. C90 does not have this clause. We only do this
1838 // if the body isn't a compound statement to avoid push/pop in common cases.
1839 //
1840 // C++ 6.5p2:
1841 // The substatement in an iteration-statement implicitly defines a local scope
1842 // which is entered and exited each time through the loop.
1843 //
1844 // See comments in ParseIfStatement for why we create a scope for the
1845 // condition and a new scope for substatement in C++.
1846 //
1847 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1848
1849 MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);
1850
1851 // Read the body statement.
1852 StmtResult Body(ParseStatement(TrailingElseLoc));
1853
1854 if (Body.isUsable())
1855 MIChecker.Check();
1856 // Pop the body scope if needed.
1857 InnerScope.Exit();
1858 WhileScope.Exit();
1859
1860 if (Cond.isInvalid() || Body.isInvalid())
1861 return StmtError();
1862
1863 return Actions.ActOnWhileStmt(WhileLoc, LParenLoc: LParen, Cond, RParenLoc: RParen, Body: Body.get());
1864}
1865
1866/// ParseDoStatement
1867/// do-statement: [C99 6.8.5.2]
1868/// 'do' statement 'while' '(' expression ')' ';'
1869/// Note: this lets the caller parse the end ';'.
1870StmtResult Parser::ParseDoStatement() {
1871 assert(Tok.is(tok::kw_do) && "Not a do stmt!");
1872 SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
1873
1874 // C99 6.8.5p5 - In C99, the do statement is a block. This is not
1875 // the case for C90. Start the loop scope.
1876 unsigned ScopeFlags;
1877 if (getLangOpts().C99)
1878 ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
1879 else
1880 ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
1881
1882 ParseScope DoScope(this, ScopeFlags);
1883
1884 // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if
1885 // there is no compound stmt. C90 does not have this clause. We only do this
1886 // if the body isn't a compound statement to avoid push/pop in common cases.
1887 //
1888 // C++ 6.5p2:
1889 // The substatement in an iteration-statement implicitly defines a local scope
1890 // which is entered and exited each time through the loop.
1891 //
1892 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1893 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1894
1895 // Read the body statement.
1896 StmtResult Body(ParseStatement());
1897
1898 // Pop the body scope if needed.
1899 InnerScope.Exit();
1900
1901 if (Tok.isNot(K: tok::kw_while)) {
1902 if (!Body.isInvalid()) {
1903 Diag(Tok, diag::err_expected_while);
1904 Diag(DoLoc, diag::note_matching) << "'do'";
1905 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
1906 }
1907 return StmtError();
1908 }
1909 SourceLocation WhileLoc = ConsumeToken();
1910
1911 if (Tok.isNot(K: tok::l_paren)) {
1912 Diag(Tok, diag::err_expected_lparen_after) << "do/while";
1913 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
1914 return StmtError();
1915 }
1916
1917 // Parse the parenthesized expression.
1918 BalancedDelimiterTracker T(*this, tok::l_paren);
1919 T.consumeOpen();
1920
1921 // A do-while expression is not a condition, so can't have attributes.
1922 DiagnoseAndSkipCXX11Attributes();
1923
1924 SourceLocation Start = Tok.getLocation();
1925 ExprResult Cond = ParseExpression();
1926 // Correct the typos in condition before closing the scope.
1927 if (Cond.isUsable())
1928 Cond = Actions.CorrectDelayedTyposInExpr(ER: Cond, /*InitDecl=*/nullptr,
1929 /*RecoverUncorrectedTypos=*/true);
1930 else {
1931 if (!Tok.isOneOf(K1: tok::r_paren, Ks: tok::r_square, Ks: tok::r_brace))
1932 SkipUntil(T: tok::semi);
1933 Cond = Actions.CreateRecoveryExpr(
1934 Begin: Start, End: Start == Tok.getLocation() ? Start : PrevTokLocation, SubExprs: {},
1935 T: Actions.getASTContext().BoolTy);
1936 }
1937 T.consumeClose();
1938 DoScope.Exit();
1939
1940 if (Cond.isInvalid() || Body.isInvalid())
1941 return StmtError();
1942
1943 return Actions.ActOnDoStmt(DoLoc, Body: Body.get(), WhileLoc, CondLParen: T.getOpenLocation(),
1944 Cond: Cond.get(), CondRParen: T.getCloseLocation());
1945}
1946
1947bool Parser::isForRangeIdentifier() {
1948 assert(Tok.is(tok::identifier));
1949
1950 const Token &Next = NextToken();
1951 if (Next.is(K: tok::colon))
1952 return true;
1953
1954 if (Next.isOneOf(K1: tok::l_square, K2: tok::kw_alignas)) {
1955 TentativeParsingAction PA(*this);
1956 ConsumeToken();
1957 SkipCXX11Attributes();
1958 bool Result = Tok.is(K: tok::colon);
1959 PA.Revert();
1960 return Result;
1961 }
1962
1963 return false;
1964}
1965
1966/// ParseForStatement
1967/// for-statement: [C99 6.8.5.3]
1968/// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
1969/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
1970/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
1971/// [C++] statement
1972/// [C++0x] 'for'
1973/// 'co_await'[opt] [Coroutines]
1974/// '(' for-range-declaration ':' for-range-initializer ')'
1975/// statement
1976/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
1977/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
1978///
1979/// [C++] for-init-statement:
1980/// [C++] expression-statement
1981/// [C++] simple-declaration
1982/// [C++23] alias-declaration
1983///
1984/// [C++0x] for-range-declaration:
1985/// [C++0x] attribute-specifier-seq[opt] type-specifier-seq declarator
1986/// [C++0x] for-range-initializer:
1987/// [C++0x] expression
1988/// [C++0x] braced-init-list [TODO]
1989StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
1990 assert(Tok.is(tok::kw_for) && "Not a for stmt!");
1991 SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
1992
1993 SourceLocation CoawaitLoc;
1994 if (Tok.is(K: tok::kw_co_await))
1995 CoawaitLoc = ConsumeToken();
1996
1997 if (Tok.isNot(K: tok::l_paren)) {
1998 Diag(Tok, diag::err_expected_lparen_after) << "for";
1999 SkipUntil(T: tok::semi);
2000 return StmtError();
2001 }
2002
2003 bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||
2004 getLangOpts().ObjC;
2005
2006 // C99 6.8.5p5 - In C99, the for statement is a block. This is not
2007 // the case for C90. Start the loop scope.
2008 //
2009 // C++ 6.4p3:
2010 // A name introduced by a declaration in a condition is in scope from its
2011 // point of declaration until the end of the substatements controlled by the
2012 // condition.
2013 // C++ 3.3.2p4:
2014 // Names declared in the for-init-statement, and in the condition of if,
2015 // while, for, and switch statements are local to the if, while, for, or
2016 // switch statement (including the controlled statement).
2017 // C++ 6.5.3p1:
2018 // Names declared in the for-init-statement are in the same declarative-region
2019 // as those declared in the condition.
2020 //
2021 unsigned ScopeFlags = 0;
2022 if (C99orCXXorObjC)
2023 ScopeFlags = Scope::DeclScope | Scope::ControlScope;
2024
2025 ParseScope ForScope(this, ScopeFlags);
2026
2027 BalancedDelimiterTracker T(*this, tok::l_paren);
2028 T.consumeOpen();
2029
2030 ExprResult Value;
2031
2032 bool ForEach = false;
2033 StmtResult FirstPart;
2034 Sema::ConditionResult SecondPart;
2035 ExprResult Collection;
2036 ForRangeInfo ForRangeInfo;
2037 FullExprArg ThirdPart(Actions);
2038
2039 if (Tok.is(K: tok::code_completion)) {
2040 cutOffParsing();
2041 Actions.CodeCompleteOrdinaryName(S: getCurScope(),
2042 CompletionContext: C99orCXXorObjC? Sema::PCC_ForInit
2043 : Sema::PCC_Expression);
2044 return StmtError();
2045 }
2046
2047 ParsedAttributes attrs(AttrFactory);
2048 MaybeParseCXX11Attributes(Attrs&: attrs);
2049
2050 SourceLocation EmptyInitStmtSemiLoc;
2051
2052 // Parse the first part of the for specifier.
2053 if (Tok.is(K: tok::semi)) { // for (;
2054 ProhibitAttributes(Attrs&: attrs);
2055 // no first part, eat the ';'.
2056 SourceLocation SemiLoc = Tok.getLocation();
2057 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID())
2058 EmptyInitStmtSemiLoc = SemiLoc;
2059 ConsumeToken();
2060 } else if (getLangOpts().CPlusPlus && Tok.is(K: tok::identifier) &&
2061 isForRangeIdentifier()) {
2062 ProhibitAttributes(Attrs&: attrs);
2063 IdentifierInfo *Name = Tok.getIdentifierInfo();
2064 SourceLocation Loc = ConsumeToken();
2065 MaybeParseCXX11Attributes(Attrs&: attrs);
2066
2067 ForRangeInfo.ColonLoc = ConsumeToken();
2068 if (Tok.is(K: tok::l_brace))
2069 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2070 else
2071 ForRangeInfo.RangeExpr = ParseExpression();
2072
2073 Diag(Loc, diag::err_for_range_identifier)
2074 << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus17)
2075 ? FixItHint::CreateInsertion(Loc, "auto &&")
2076 : FixItHint());
2077
2078 ForRangeInfo.LoopVar =
2079 Actions.ActOnCXXForRangeIdentifier(S: getCurScope(), IdentLoc: Loc, Ident: Name, Attrs&: attrs);
2080 } else if (isForInitDeclaration()) { // for (int X = 4;
2081 ParenBraceBracketBalancer BalancerRAIIObj(*this);
2082
2083 // Parse declaration, which eats the ';'.
2084 if (!C99orCXXorObjC) { // Use of C99-style for loops in C90 mode?
2085 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2086 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2087 }
2088 DeclGroupPtrTy DG;
2089 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2090 if (Tok.is(K: tok::kw_using)) {
2091 DG = ParseAliasDeclarationInInitStatement(Context: DeclaratorContext::ForInit,
2092 Attrs&: attrs);
2093 FirstPart = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: Tok.getLocation());
2094 } else {
2095 // In C++0x, "for (T NS:a" might not be a typo for ::
2096 bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
2097 ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
2098 ParsedAttributes DeclSpecAttrs(AttrFactory);
2099 DG = ParseSimpleDeclaration(
2100 Context: DeclaratorContext::ForInit, DeclEnd, DeclAttrs&: attrs, DeclSpecAttrs, RequireSemi: false,
2101 FRI: MightBeForRangeStmt ? &ForRangeInfo : nullptr);
2102 FirstPart = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: Tok.getLocation());
2103 if (ForRangeInfo.ParsedForRangeDecl()) {
2104 Diag(ForRangeInfo.ColonLoc, getLangOpts().CPlusPlus11
2105 ? diag::warn_cxx98_compat_for_range
2106 : diag::ext_for_range);
2107 ForRangeInfo.LoopVar = FirstPart;
2108 FirstPart = StmtResult();
2109 } else if (Tok.is(K: tok::semi)) { // for (int x = 4;
2110 ConsumeToken();
2111 } else if ((ForEach = isTokIdentifier_in())) {
2112 Actions.ActOnForEachDeclStmt(Decl: DG);
2113 // ObjC: for (id x in expr)
2114 ConsumeToken(); // consume 'in'
2115
2116 if (Tok.is(K: tok::code_completion)) {
2117 cutOffParsing();
2118 Actions.CodeCompleteObjCForCollection(S: getCurScope(), IterationVar: DG);
2119 return StmtError();
2120 }
2121 Collection = ParseExpression();
2122 } else {
2123 Diag(Tok, diag::err_expected_semi_for);
2124 }
2125 }
2126 } else {
2127 ProhibitAttributes(Attrs&: attrs);
2128 Value = Actions.CorrectDelayedTyposInExpr(ER: ParseExpression());
2129
2130 ForEach = isTokIdentifier_in();
2131
2132 // Turn the expression into a stmt.
2133 if (!Value.isInvalid()) {
2134 if (ForEach)
2135 FirstPart = Actions.ActOnForEachLValueExpr(E: Value.get());
2136 else {
2137 // We already know this is not an init-statement within a for loop, so
2138 // if we are parsing a C++11 range-based for loop, we should treat this
2139 // expression statement as being a discarded value expression because
2140 // we will err below. This way we do not warn on an unused expression
2141 // that was an error in the first place, like with: for (expr : expr);
2142 bool IsRangeBasedFor =
2143 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(K: tok::colon);
2144 FirstPart = Actions.ActOnExprStmt(Arg: Value, DiscardedValue: !IsRangeBasedFor);
2145 }
2146 }
2147
2148 if (Tok.is(K: tok::semi)) {
2149 ConsumeToken();
2150 } else if (ForEach) {
2151 ConsumeToken(); // consume 'in'
2152
2153 if (Tok.is(K: tok::code_completion)) {
2154 cutOffParsing();
2155 Actions.CodeCompleteObjCForCollection(S: getCurScope(), IterationVar: nullptr);
2156 return StmtError();
2157 }
2158 Collection = ParseExpression();
2159 } else if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::colon) && FirstPart.get()) {
2160 // User tried to write the reasonable, but ill-formed, for-range-statement
2161 // for (expr : expr) { ... }
2162 Diag(Tok, diag::err_for_range_expected_decl)
2163 << FirstPart.get()->getSourceRange();
2164 SkipUntil(T: tok::r_paren, Flags: StopBeforeMatch);
2165 SecondPart = Sema::ConditionError();
2166 } else {
2167 if (!Value.isInvalid()) {
2168 Diag(Tok, diag::err_expected_semi_for);
2169 } else {
2170 // Skip until semicolon or rparen, don't consume it.
2171 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
2172 if (Tok.is(K: tok::semi))
2173 ConsumeToken();
2174 }
2175 }
2176 }
2177
2178 // Parse the second part of the for specifier.
2179 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2180 !SecondPart.isInvalid()) {
2181 // Parse the second part of the for specifier.
2182 if (Tok.is(K: tok::semi)) { // for (...;;
2183 // no second part.
2184 } else if (Tok.is(K: tok::r_paren)) {
2185 // missing both semicolons.
2186 } else {
2187 if (getLangOpts().CPlusPlus) {
2188 // C++2a: We've parsed an init-statement; we might have a
2189 // for-range-declaration next.
2190 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2191 ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
2192 SourceLocation SecondPartStart = Tok.getLocation();
2193 Sema::ConditionKind CK = Sema::ConditionKind::Boolean;
2194 SecondPart = ParseCXXCondition(
2195 /*InitStmt=*/nullptr, Loc: ForLoc, CK,
2196 // FIXME: recovery if we don't see another semi!
2197 /*MissingOK=*/true, FRI: MightBeForRangeStmt ? &ForRangeInfo : nullptr,
2198 /*EnterForConditionScope=*/true);
2199
2200 if (ForRangeInfo.ParsedForRangeDecl()) {
2201 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2202 : ForRangeInfo.ColonLoc,
2203 getLangOpts().CPlusPlus20
2204 ? diag::warn_cxx17_compat_for_range_init_stmt
2205 : diag::ext_for_range_init_stmt)
2206 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2207 : SourceRange());
2208 if (EmptyInitStmtSemiLoc.isValid()) {
2209 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2210 << /*for-loop*/ 2
2211 << FixItHint::CreateRemoval(EmptyInitStmtSemiLoc);
2212 }
2213 }
2214
2215 if (SecondPart.isInvalid()) {
2216 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2217 Begin: SecondPartStart,
2218 End: Tok.getLocation() == SecondPartStart ? SecondPartStart
2219 : PrevTokLocation,
2220 SubExprs: {}, T: Actions.PreferredConditionType(K: CK));
2221 if (!CondExpr.isInvalid())
2222 SecondPart = Actions.ActOnCondition(S: getCurScope(), Loc: ForLoc,
2223 SubExpr: CondExpr.get(), CK,
2224 /*MissingOK=*/false);
2225 }
2226
2227 } else {
2228 // We permit 'continue' and 'break' in the condition of a for loop.
2229 getCurScope()->AddFlags(Flags: Scope::BreakScope | Scope::ContinueScope);
2230
2231 ExprResult SecondExpr = ParseExpression();
2232 if (SecondExpr.isInvalid())
2233 SecondPart = Sema::ConditionError();
2234 else
2235 SecondPart = Actions.ActOnCondition(
2236 S: getCurScope(), Loc: ForLoc, SubExpr: SecondExpr.get(),
2237 CK: Sema::ConditionKind::Boolean, /*MissingOK=*/true);
2238 }
2239 }
2240 }
2241
2242 // Enter a break / continue scope, if we didn't already enter one while
2243 // parsing the second part.
2244 if (!getCurScope()->isContinueScope())
2245 getCurScope()->AddFlags(Flags: Scope::BreakScope | Scope::ContinueScope);
2246
2247 // Parse the third part of the for statement.
2248 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2249 if (Tok.isNot(K: tok::semi)) {
2250 if (!SecondPart.isInvalid())
2251 Diag(Tok, diag::err_expected_semi_for);
2252 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
2253 }
2254
2255 if (Tok.is(K: tok::semi)) {
2256 ConsumeToken();
2257 }
2258
2259 if (Tok.isNot(K: tok::r_paren)) { // for (...;...;)
2260 ExprResult Third = ParseExpression();
2261 // FIXME: The C++11 standard doesn't actually say that this is a
2262 // discarded-value expression, but it clearly should be.
2263 ThirdPart = Actions.MakeFullDiscardedValueExpr(Arg: Third.get());
2264 }
2265 }
2266 // Match the ')'.
2267 T.consumeClose();
2268
2269 // C++ Coroutines [stmt.iter]:
2270 // 'co_await' can only be used for a range-based for statement.
2271 if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2272 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2273 CoawaitLoc = SourceLocation();
2274 }
2275
2276 if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20)
2277 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2278
2279 // We need to perform most of the semantic analysis for a C++0x for-range
2280 // statememt before parsing the body, in order to be able to deduce the type
2281 // of an auto-typed loop variable.
2282 StmtResult ForRangeStmt;
2283 StmtResult ForEachStmt;
2284
2285 if (ForRangeInfo.ParsedForRangeDecl()) {
2286 ExprResult CorrectedRange =
2287 Actions.CorrectDelayedTyposInExpr(E: ForRangeInfo.RangeExpr.get());
2288 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2289 S: getCurScope(), ForLoc, CoawaitLoc, InitStmt: FirstPart.get(),
2290 LoopVar: ForRangeInfo.LoopVar.get(), ColonLoc: ForRangeInfo.ColonLoc, Collection: CorrectedRange.get(),
2291 RParenLoc: T.getCloseLocation(), Kind: Sema::BFRK_Build,
2292 LifetimeExtendTemps: ForRangeInfo.LifetimeExtendTemps);
2293 } else if (ForEach) {
2294 // Similarly, we need to do the semantic analysis for a for-range
2295 // statement immediately in order to close over temporaries correctly.
2296 ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForColLoc: ForLoc,
2297 First: FirstPart.get(),
2298 collection: Collection.get(),
2299 RParenLoc: T.getCloseLocation());
2300 } else {
2301 // In OpenMP loop region loop control variable must be captured and be
2302 // private. Perform analysis of first part (if any).
2303 if (getLangOpts().OpenMP && FirstPart.isUsable()) {
2304 Actions.ActOnOpenMPLoopInitialization(ForLoc, Init: FirstPart.get());
2305 }
2306 }
2307
2308 // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
2309 // there is no compound stmt. C90 does not have this clause. We only do this
2310 // if the body isn't a compound statement to avoid push/pop in common cases.
2311 //
2312 // C++ 6.5p2:
2313 // The substatement in an iteration-statement implicitly defines a local scope
2314 // which is entered and exited each time through the loop.
2315 //
2316 // See comments in ParseIfStatement for why we create a scope for
2317 // for-init-statement/condition and a new scope for substatement in C++.
2318 //
2319 ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
2320 Tok.is(K: tok::l_brace));
2321
2322 // The body of the for loop has the same local mangling number as the
2323 // for-init-statement.
2324 // It will only be incremented if the body contains other things that would
2325 // normally increment the mangling number (like a compound statement).
2326 if (C99orCXXorObjC)
2327 getCurScope()->decrementMSManglingNumber();
2328
2329 MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);
2330
2331 // Read the body statement.
2332 StmtResult Body(ParseStatement(TrailingElseLoc));
2333
2334 if (Body.isUsable())
2335 MIChecker.Check();
2336
2337 // Pop the body scope if needed.
2338 InnerScope.Exit();
2339
2340 // Leave the for-scope.
2341 ForScope.Exit();
2342
2343 if (Body.isInvalid())
2344 return StmtError();
2345
2346 if (ForEach)
2347 return Actions.FinishObjCForCollectionStmt(ForCollection: ForEachStmt.get(),
2348 Body: Body.get());
2349
2350 if (ForRangeInfo.ParsedForRangeDecl())
2351 return Actions.FinishCXXForRangeStmt(ForRange: ForRangeStmt.get(), Body: Body.get());
2352
2353 return Actions.ActOnForStmt(ForLoc, LParenLoc: T.getOpenLocation(), First: FirstPart.get(),
2354 Second: SecondPart, Third: ThirdPart, RParenLoc: T.getCloseLocation(),
2355 Body: Body.get());
2356}
2357
2358/// ParseGotoStatement
2359/// jump-statement:
2360/// 'goto' identifier ';'
2361/// [GNU] 'goto' '*' expression ';'
2362///
2363/// Note: this lets the caller parse the end ';'.
2364///
2365StmtResult Parser::ParseGotoStatement() {
2366 assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
2367 SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
2368
2369 StmtResult Res;
2370 if (Tok.is(K: tok::identifier)) {
2371 LabelDecl *LD = Actions.LookupOrCreateLabel(II: Tok.getIdentifierInfo(),
2372 IdentLoc: Tok.getLocation());
2373 Res = Actions.ActOnGotoStmt(GotoLoc, LabelLoc: Tok.getLocation(), TheDecl: LD);
2374 ConsumeToken();
2375 } else if (Tok.is(K: tok::star)) {
2376 // GNU indirect goto extension.
2377 Diag(Tok, diag::ext_gnu_indirect_goto);
2378 SourceLocation StarLoc = ConsumeToken();
2379 ExprResult R(ParseExpression());
2380 if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
2381 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
2382 return StmtError();
2383 }
2384 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, DestExp: R.get());
2385 } else {
2386 Diag(Tok, diag::err_expected) << tok::identifier;
2387 return StmtError();
2388 }
2389
2390 return Res;
2391}
2392
2393/// ParseContinueStatement
2394/// jump-statement:
2395/// 'continue' ';'
2396///
2397/// Note: this lets the caller parse the end ';'.
2398///
2399StmtResult Parser::ParseContinueStatement() {
2400 SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
2401 return Actions.ActOnContinueStmt(ContinueLoc, CurScope: getCurScope());
2402}
2403
2404/// ParseBreakStatement
2405/// jump-statement:
2406/// 'break' ';'
2407///
2408/// Note: this lets the caller parse the end ';'.
2409///
2410StmtResult Parser::ParseBreakStatement() {
2411 SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
2412 return Actions.ActOnBreakStmt(BreakLoc, CurScope: getCurScope());
2413}
2414
2415/// ParseReturnStatement
2416/// jump-statement:
2417/// 'return' expression[opt] ';'
2418/// 'return' braced-init-list ';'
2419/// 'co_return' expression[opt] ';'
2420/// 'co_return' braced-init-list ';'
2421StmtResult Parser::ParseReturnStatement() {
2422 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2423 "Not a return stmt!");
2424 bool IsCoreturn = Tok.is(K: tok::kw_co_return);
2425 SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
2426
2427 ExprResult R;
2428 if (Tok.isNot(K: tok::semi)) {
2429 if (!IsCoreturn)
2430 PreferredType.enterReturn(Actions, Tok.getLocation());
2431 // FIXME: Code completion for co_return.
2432 if (Tok.is(K: tok::code_completion) && !IsCoreturn) {
2433 cutOffParsing();
2434 Actions.CodeCompleteExpression(getCurScope(),
2435 PreferredType.get(Tok.getLocation()));
2436 return StmtError();
2437 }
2438
2439 if (Tok.is(K: tok::l_brace) && getLangOpts().CPlusPlus) {
2440 R = ParseInitializer();
2441 if (R.isUsable())
2442 Diag(R.get()->getBeginLoc(),
2443 getLangOpts().CPlusPlus11
2444 ? diag::warn_cxx98_compat_generalized_initializer_lists
2445 : diag::ext_generalized_initializer_lists)
2446 << R.get()->getSourceRange();
2447 } else
2448 R = ParseExpression();
2449 if (R.isInvalid()) {
2450 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
2451 return StmtError();
2452 }
2453 }
2454 if (IsCoreturn)
2455 return Actions.ActOnCoreturnStmt(S: getCurScope(), KwLoc: ReturnLoc, E: R.get());
2456 return Actions.ActOnReturnStmt(ReturnLoc, RetValExp: R.get(), CurScope: getCurScope());
2457}
2458
2459StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2460 ParsedStmtContext StmtCtx,
2461 SourceLocation *TrailingElseLoc,
2462 ParsedAttributes &Attrs) {
2463 // Create temporary attribute list.
2464 ParsedAttributes TempAttrs(AttrFactory);
2465
2466 SourceLocation StartLoc = Tok.getLocation();
2467
2468 // Get loop hints and consume annotated token.
2469 while (Tok.is(K: tok::annot_pragma_loop_hint)) {
2470 LoopHint Hint;
2471 if (!HandlePragmaLoopHint(Hint))
2472 continue;
2473
2474 ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.StateLoc,
2475 ArgsUnion(Hint.ValueExpr)};
2476 TempAttrs.addNew(attrName: Hint.PragmaNameLoc->Ident, attrRange: Hint.Range, scopeName: nullptr,
2477 scopeLoc: Hint.PragmaNameLoc->Loc, args: ArgHints, numArgs: 4,
2478 form: ParsedAttr::Form::Pragma());
2479 }
2480
2481 // Get the next statement.
2482 MaybeParseCXX11Attributes(Attrs);
2483
2484 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2485 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2486 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs&: Attrs, GNUAttrs&: EmptyDeclSpecAttrs);
2487
2488 Attrs.takeAllFrom(Other&: TempAttrs);
2489
2490 // Start of attribute range may already be set for some invalid input.
2491 // See PR46336.
2492 if (Attrs.Range.getBegin().isInvalid())
2493 Attrs.Range.setBegin(StartLoc);
2494
2495 return S;
2496}
2497
2498Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
2499 assert(Tok.is(tok::l_brace));
2500 SourceLocation LBraceLoc = Tok.getLocation();
2501
2502 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2503 "parsing function body");
2504
2505 // Save and reset current vtordisp stack if we have entered a C++ method body.
2506 bool IsCXXMethod =
2507 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Val: Decl);
2508 Sema::PragmaStackSentinelRAII
2509 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2510
2511 // Do not enter a scope for the brace, as the arguments are in the same scope
2512 // (the function body) as the body itself. Instead, just read the statement
2513 // list and put it into a CompoundStmt for safe keeping.
2514 StmtResult FnBody(ParseCompoundStatementBody());
2515
2516 // If the function body could not be parsed, make a bogus compoundstmt.
2517 if (FnBody.isInvalid()) {
2518 Sema::CompoundScopeRAII CompoundScope(Actions);
2519 FnBody =
2520 Actions.ActOnCompoundStmt(L: LBraceLoc, R: LBraceLoc, Elts: std::nullopt, isStmtExpr: false);
2521 }
2522
2523 BodyScope.Exit();
2524 return Actions.ActOnFinishFunctionBody(Decl, Body: FnBody.get());
2525}
2526
2527/// ParseFunctionTryBlock - Parse a C++ function-try-block.
2528///
2529/// function-try-block:
2530/// 'try' ctor-initializer[opt] compound-statement handler-seq
2531///
2532Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
2533 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2534 SourceLocation TryLoc = ConsumeToken();
2535
2536 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2537 "parsing function try block");
2538
2539 // Constructor initializer list?
2540 if (Tok.is(K: tok::colon))
2541 ParseConstructorInitializer(ConstructorDecl: Decl);
2542 else
2543 Actions.ActOnDefaultCtorInitializers(CDtorDecl: Decl);
2544
2545 // Save and reset current vtordisp stack if we have entered a C++ method body.
2546 bool IsCXXMethod =
2547 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Val: Decl);
2548 Sema::PragmaStackSentinelRAII
2549 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2550
2551 SourceLocation LBraceLoc = Tok.getLocation();
2552 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));
2553 // If we failed to parse the try-catch, we just give the function an empty
2554 // compound statement as the body.
2555 if (FnBody.isInvalid()) {
2556 Sema::CompoundScopeRAII CompoundScope(Actions);
2557 FnBody =
2558 Actions.ActOnCompoundStmt(L: LBraceLoc, R: LBraceLoc, Elts: std::nullopt, isStmtExpr: false);
2559 }
2560
2561 BodyScope.Exit();
2562 return Actions.ActOnFinishFunctionBody(Decl, Body: FnBody.get());
2563}
2564
2565bool Parser::trySkippingFunctionBody() {
2566 assert(SkipFunctionBodies &&
2567 "Should only be called when SkipFunctionBodies is enabled");
2568 if (!PP.isCodeCompletionEnabled()) {
2569 SkipFunctionBody();
2570 return true;
2571 }
2572
2573 // We're in code-completion mode. Skip parsing for all function bodies unless
2574 // the body contains the code-completion point.
2575 TentativeParsingAction PA(*this);
2576 bool IsTryCatch = Tok.is(K: tok::kw_try);
2577 CachedTokens Toks;
2578 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2579 if (llvm::any_of(Range&: Toks, P: [](const Token &Tok) {
2580 return Tok.is(K: tok::code_completion);
2581 })) {
2582 PA.Revert();
2583 return false;
2584 }
2585 if (ErrorInPrologue) {
2586 PA.Commit();
2587 SkipMalformedDecl();
2588 return true;
2589 }
2590 if (!SkipUntil(T: tok::r_brace, Flags: StopAtCodeCompletion)) {
2591 PA.Revert();
2592 return false;
2593 }
2594 while (IsTryCatch && Tok.is(K: tok::kw_catch)) {
2595 if (!SkipUntil(T: tok::l_brace, Flags: StopAtCodeCompletion) ||
2596 !SkipUntil(T: tok::r_brace, Flags: StopAtCodeCompletion)) {
2597 PA.Revert();
2598 return false;
2599 }
2600 }
2601 PA.Commit();
2602 return true;
2603}
2604
2605/// ParseCXXTryBlock - Parse a C++ try-block.
2606///
2607/// try-block:
2608/// 'try' compound-statement handler-seq
2609///
2610StmtResult Parser::ParseCXXTryBlock() {
2611 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2612
2613 SourceLocation TryLoc = ConsumeToken();
2614 return ParseCXXTryBlockCommon(TryLoc);
2615}
2616
2617/// ParseCXXTryBlockCommon - Parse the common part of try-block and
2618/// function-try-block.
2619///
2620/// try-block:
2621/// 'try' compound-statement handler-seq
2622///
2623/// function-try-block:
2624/// 'try' ctor-initializer[opt] compound-statement handler-seq
2625///
2626/// handler-seq:
2627/// handler handler-seq[opt]
2628///
2629/// [Borland] try-block:
2630/// 'try' compound-statement seh-except-block
2631/// 'try' compound-statement seh-finally-block
2632///
2633StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
2634 if (Tok.isNot(tok::l_brace))
2635 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
2636
2637 StmtResult TryBlock(ParseCompoundStatement(
2638 /*isStmtExpr=*/false, ScopeFlags: Scope::DeclScope | Scope::TryScope |
2639 Scope::CompoundStmtScope |
2640 (FnTry ? Scope::FnTryCatchScope : 0)));
2641 if (TryBlock.isInvalid())
2642 return TryBlock;
2643
2644 // Borland allows SEH-handlers with 'try'
2645
2646 if ((Tok.is(K: tok::identifier) &&
2647 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2648 Tok.is(K: tok::kw___finally)) {
2649 // TODO: Factor into common return ParseSEHHandlerCommon(...)
2650 StmtResult Handler;
2651 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2652 SourceLocation Loc = ConsumeToken();
2653 Handler = ParseSEHExceptBlock(ExceptLoc: Loc);
2654 }
2655 else {
2656 SourceLocation Loc = ConsumeToken();
2657 Handler = ParseSEHFinallyBlock(FinallyLoc: Loc);
2658 }
2659 if(Handler.isInvalid())
2660 return Handler;
2661
2662 return Actions.ActOnSEHTryBlock(IsCXXTry: true /* IsCXXTry */,
2663 TryLoc,
2664 TryBlock: TryBlock.get(),
2665 Handler: Handler.get());
2666 }
2667 else {
2668 StmtVector Handlers;
2669
2670 // C++11 attributes can't appear here, despite this context seeming
2671 // statement-like.
2672 DiagnoseAndSkipCXX11Attributes();
2673
2674 if (Tok.isNot(tok::kw_catch))
2675 return StmtError(Diag(Tok, diag::err_expected_catch));
2676 while (Tok.is(K: tok::kw_catch)) {
2677 StmtResult Handler(ParseCXXCatchBlock(FnCatch: FnTry));
2678 if (!Handler.isInvalid())
2679 Handlers.push_back(Elt: Handler.get());
2680 }
2681 // Don't bother creating the full statement if we don't have any usable
2682 // handlers.
2683 if (Handlers.empty())
2684 return StmtError();
2685
2686 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock: TryBlock.get(), Handlers);
2687 }
2688}
2689
2690/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
2691///
2692/// handler:
2693/// 'catch' '(' exception-declaration ')' compound-statement
2694///
2695/// exception-declaration:
2696/// attribute-specifier-seq[opt] type-specifier-seq declarator
2697/// attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
2698/// '...'
2699///
2700StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
2701 assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
2702
2703 SourceLocation CatchLoc = ConsumeToken();
2704
2705 BalancedDelimiterTracker T(*this, tok::l_paren);
2706 if (T.expectAndConsume())
2707 return StmtError();
2708
2709 // C++ 3.3.2p3:
2710 // The name in a catch exception-declaration is local to the handler and
2711 // shall not be redeclared in the outermost block of the handler.
2712 ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
2713 Scope::CatchScope |
2714 (FnCatch ? Scope::FnTryCatchScope : 0));
2715
2716 // exception-declaration is equivalent to '...' or a parameter-declaration
2717 // without default arguments.
2718 Decl *ExceptionDecl = nullptr;
2719 if (Tok.isNot(K: tok::ellipsis)) {
2720 ParsedAttributes Attributes(AttrFactory);
2721 MaybeParseCXX11Attributes(Attrs&: Attributes);
2722
2723 DeclSpec DS(AttrFactory);
2724
2725 if (ParseCXXTypeSpecifierSeq(DS))
2726 return StmtError();
2727
2728 Declarator ExDecl(DS, Attributes, DeclaratorContext::CXXCatch);
2729 ParseDeclarator(D&: ExDecl);
2730 ExceptionDecl = Actions.ActOnExceptionDeclarator(S: getCurScope(), D&: ExDecl);
2731 } else
2732 ConsumeToken();
2733
2734 T.consumeClose();
2735 if (T.getCloseLocation().isInvalid())
2736 return StmtError();
2737
2738 if (Tok.isNot(tok::l_brace))
2739 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
2740
2741 // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
2742 StmtResult Block(ParseCompoundStatement());
2743 if (Block.isInvalid())
2744 return Block;
2745
2746 return Actions.ActOnCXXCatchBlock(CatchLoc, ExDecl: ExceptionDecl, HandlerBlock: Block.get());
2747}
2748
2749void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2750 IfExistsCondition Result;
2751 if (ParseMicrosoftIfExistsCondition(Result))
2752 return;
2753
2754 // Handle dependent statements by parsing the braces as a compound statement.
2755 // This is not the same behavior as Visual C++, which don't treat this as a
2756 // compound statement, but for Clang's type checking we can't have anything
2757 // inside these braces escaping to the surrounding code.
2758 if (Result.Behavior == IEB_Dependent) {
2759 if (!Tok.is(K: tok::l_brace)) {
2760 Diag(Tok, diag::err_expected) << tok::l_brace;
2761 return;
2762 }
2763
2764 StmtResult Compound = ParseCompoundStatement();
2765 if (Compound.isInvalid())
2766 return;
2767
2768 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(KeywordLoc: Result.KeywordLoc,
2769 IsIfExists: Result.IsIfExists,
2770 SS&: Result.SS,
2771 Name&: Result.Name,
2772 Nested: Compound.get());
2773 if (DepResult.isUsable())
2774 Stmts.push_back(Elt: DepResult.get());
2775 return;
2776 }
2777
2778 BalancedDelimiterTracker Braces(*this, tok::l_brace);
2779 if (Braces.consumeOpen()) {
2780 Diag(Tok, diag::err_expected) << tok::l_brace;
2781 return;
2782 }
2783
2784 switch (Result.Behavior) {
2785 case IEB_Parse:
2786 // Parse the statements below.
2787 break;
2788
2789 case IEB_Dependent:
2790 llvm_unreachable("Dependent case handled above");
2791
2792 case IEB_Skip:
2793 Braces.skipToEnd();
2794 return;
2795 }
2796
2797 // Condition is true, parse the statements.
2798 while (Tok.isNot(K: tok::r_brace)) {
2799 StmtResult R =
2800 ParseStatementOrDeclaration(Stmts, StmtCtx: ParsedStmtContext::Compound);
2801 if (R.isUsable())
2802 Stmts.push_back(Elt: R.get());
2803 }
2804 Braces.consumeClose();
2805}
2806

source code of clang/lib/Parse/ParseStmt.cpp