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