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

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