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
32using 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').
40StmtResult 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///
103StmtResult
104Parser::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(Attrs&: CXX11Attrs, /*MightBeObjCMessageSend*/ OuterMightBeMessageSend: true);
117 ParsedAttributes GNUOrMSAttrs(AttrFactory);
118 if (getLangOpts().OpenCL)
119 MaybeParseGNUAttributes(Attrs&: GNUOrMSAttrs);
120
121 if (getLangOpts().HLSL)
122 MaybeParseMicrosoftAttributes(Attrs&: GNUOrMSAttrs);
123
124 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
125 Stmts, StmtCtx, TrailingElseLoc, DeclAttrs&: CXX11Attrs, DeclSpecAttrs&: 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(First&: CXX11Attrs, Second&: GNUOrMSAttrs, Result&: 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(AttrList: Attrs, SubStmt: Res.get());
140}
141
142namespace {
143class StatementFilterCCC final : public CorrectionCandidateCallback {
144public:
145 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
146 WantTypeSpecifiers = nextTok.isOneOf(K1: tok::l_paren, Ks: tok::less, Ks: tok::l_square,
147 Ks: tok::identifier, Ks: tok::star, Ks: tok::amp);
148 WantExpressionKeywords =
149 nextTok.isOneOf(K1: tok::l_paren, Ks: tok::identifier, Ks: tok::arrow, Ks: tok::period);
150 WantRemainingKeywords =
151 nextTok.isOneOf(K1: tok::l_paren, Ks: tok::semi, Ks: tok::identifier, Ks: tok::l_brace);
152 WantCXXNamedCasts = false;
153 }
154
155 bool ValidateCandidate(const TypoCorrection &candidate) override {
156 if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
157 return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(Val: FD);
158 if (NextToken.is(K: tok::equal))
159 return candidate.getCorrectionDeclAs<VarDecl>();
160 if (NextToken.is(K: tok::period) &&
161 candidate.getCorrectionDeclAs<NamespaceDecl>())
162 return false;
163 return CorrectionCandidateCallback::ValidateCandidate(candidate);
164 }
165
166 std::unique_ptr<CorrectionCandidateCallback> clone() override {
167 return std::make_unique<StatementFilterCCC>(args&: *this);
168 }
169
170private:
171 Token NextToken;
172};
173}
174
175StmtResult 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.
186Retry:
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: AtLoc, StmtCtx);
194 }
195
196 case tok::code_completion:
197 cutOffParsing();
198 Actions.CodeCompletion().CodeCompleteOrdinaryName(
199 S: getCurScope(), CompletionContext: SemaCodeCompletion::PCC_Statement);
200 return StmtError();
201
202 case tok::identifier:
203 ParseIdentifier: {
204 Token Next = NextToken();
205 if (Next.is(K: 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(First&: CXX11Attrs, Second&: GNUAttrs, Result&: 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(K: 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: &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(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
226 if (Tok.is(K: tok::semi))
227 ConsumeToken();
228 return StmtError();
229 }
230
231 // If the identifier was typo-corrected, try again.
232 if (Tok.isNot(K: 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(Range&: CXX11Attrs, P: IsStmtAttr) &&
244 llvm::all_of(Range&: GNUAttrs, P: 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(Context: DeclaratorContext::Block, DeclEnd, DeclAttrs&: CXX11Attrs,
260 DeclSpecAttrs&: GNUAttrs, DeclSpecStart: &GNUAttributeLoc);
261 } else {
262 Decl = ParseDeclaration(Context: DeclaratorContext::Block, DeclEnd, DeclAttrs&: CXX11Attrs,
263 DeclSpecAttrs&: 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, StartLoc: DeclStart, EndLoc: DeclEnd);
274 }
275
276 if (Tok.is(K: tok::r_brace)) {
277 Diag(Tok, DiagID: 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(K: tok::less)) {
285 Tok.setKind(tok::identifier);
286 Diag(Tok, DiagID: 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(Attrs&: 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(SemiLoc: 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(Loc: AL.getRange().getBegin(), DiagID: diag::err_keyword_not_allowed)
355 : Diag(Loc: AL.getRange().getBegin(), DiagID: diag::warn_attribute_ignored))
356 << AL;
357 // Prevent these from being interpreted as statement attributes later on.
358 CXX11Attrs.clear();
359 ProhibitAttributes(Attrs&: 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(Attrs&: CXX11Attrs);
370 ProhibitAttributes(Attrs&: 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(Attrs&: CXX11Attrs);
381 ProhibitAttributes(Attrs&: 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(Attrs&: CXX11Attrs);
391 ProhibitAttributes(Attrs&: GNUAttrs);
392 HandlePragmaVisibility();
393 return StmtEmpty();
394
395 case tok::annot_pragma_pack:
396 ProhibitAttributes(Attrs&: CXX11Attrs);
397 ProhibitAttributes(Attrs&: GNUAttrs);
398 HandlePragmaPack();
399 return StmtEmpty();
400
401 case tok::annot_pragma_msstruct:
402 ProhibitAttributes(Attrs&: CXX11Attrs);
403 ProhibitAttributes(Attrs&: GNUAttrs);
404 HandlePragmaMSStruct();
405 return StmtEmpty();
406
407 case tok::annot_pragma_align:
408 ProhibitAttributes(Attrs&: CXX11Attrs);
409 ProhibitAttributes(Attrs&: GNUAttrs);
410 HandlePragmaAlign();
411 return StmtEmpty();
412
413 case tok::annot_pragma_weak:
414 ProhibitAttributes(Attrs&: CXX11Attrs);
415 ProhibitAttributes(Attrs&: GNUAttrs);
416 HandlePragmaWeak();
417 return StmtEmpty();
418
419 case tok::annot_pragma_weakalias:
420 ProhibitAttributes(Attrs&: CXX11Attrs);
421 ProhibitAttributes(Attrs&: GNUAttrs);
422 HandlePragmaWeakAlias();
423 return StmtEmpty();
424
425 case tok::annot_pragma_redefine_extname:
426 ProhibitAttributes(Attrs&: CXX11Attrs);
427 ProhibitAttributes(Attrs&: GNUAttrs);
428 HandlePragmaRedefineExtname();
429 return StmtEmpty();
430
431 case tok::annot_pragma_fp_contract:
432 ProhibitAttributes(Attrs&: CXX11Attrs);
433 ProhibitAttributes(Attrs&: GNUAttrs);
434 Diag(Tok, DiagID: diag::err_pragma_file_or_compound_scope) << "fp_contract";
435 ConsumeAnnotationToken();
436 return StmtError();
437
438 case tok::annot_pragma_fp:
439 ProhibitAttributes(Attrs&: CXX11Attrs);
440 ProhibitAttributes(Attrs&: GNUAttrs);
441 Diag(Tok, DiagID: 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(Attrs&: CXX11Attrs);
448 ProhibitAttributes(Attrs&: GNUAttrs);
449 Diag(Tok, DiagID: 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(Attrs&: CXX11Attrs);
457 ProhibitAttributes(Attrs&: GNUAttrs);
458 Diag(Tok, DiagID: 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(Attrs&: CXX11Attrs);
464 ProhibitAttributes(Attrs&: GNUAttrs);
465 Diag(Tok, DiagID: 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(Attrs&: CXX11Attrs);
472 ProhibitAttributes(Attrs&: GNUAttrs);
473 Diag(Tok, DiagID: diag::err_pragma_file_or_compound_scope) << "float_control";
474 ConsumeAnnotationToken();
475 return StmtError();
476
477 case tok::annot_pragma_opencl_extension:
478 ProhibitAttributes(Attrs&: CXX11Attrs);
479 ProhibitAttributes(Attrs&: GNUAttrs);
480 HandlePragmaOpenCLExtension();
481 return StmtEmpty();
482
483 case tok::annot_pragma_captured:
484 ProhibitAttributes(Attrs&: CXX11Attrs);
485 ProhibitAttributes(Attrs&: 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(Attrs&: CXX11Attrs);
492 ProhibitAttributes(Attrs&: 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(Attrs&: CXX11Attrs);
503 ProhibitAttributes(Attrs&: GNUAttrs);
504 HandlePragmaMSPointersToMembers();
505 return StmtEmpty();
506
507 case tok::annot_pragma_ms_pragma:
508 ProhibitAttributes(Attrs&: CXX11Attrs);
509 ProhibitAttributes(Attrs&: GNUAttrs);
510 HandlePragmaMSPragma();
511 return StmtEmpty();
512
513 case tok::annot_pragma_ms_vtordisp:
514 ProhibitAttributes(Attrs&: CXX11Attrs);
515 ProhibitAttributes(Attrs&: GNUAttrs);
516 HandlePragmaMSVtorDisp();
517 return StmtEmpty();
518
519 case tok::annot_pragma_loop_hint:
520 ProhibitAttributes(Attrs&: CXX11Attrs);
521 ProhibitAttributes(Attrs&: GNUAttrs);
522 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs&: 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(Expected: 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(ExpectedTok: tok::semi, Diag: diag::err_expected_semi_after_stmt, DiagMsg: SemiError);
539 // Skip until we see a } or ;, but don't eat it.
540 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
541 }
542
543 return Res;
544}
545
546/// Parse an expression statement.
547StmtResult 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(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
560 if (Tok.is(K: tok::semi))
561 ConsumeToken();
562 return Actions.ActOnExprStmtError();
563 }
564
565 if (Tok.is(K: tok::colon) && getCurScope()->isSwitchScope() &&
566 Actions.CheckCaseExpression(E: Expr.get())) {
567 // If a constant expression is followed by a colon inside a switch block,
568 // suggest a missing case keyword.
569 Diag(Tok: OldToken, DiagID: diag::err_expected_case_before_expression)
570 << FixItHint::CreateInsertion(InsertionLoc: OldToken.getLocation(), Code: "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(K: tok::annot_repl_input_end))
579 CurTok = &Tok;
580 else
581 // Otherwise, eat the semicolon.
582 ExpectAndConsumeSemi(DiagID: diag::err_expected_semi_after_expr);
583
584 StmtResult R = handleExprStmt(E: 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///
600StmtResult Parser::ParseSEHTryBlock() {
601 assert(Tok.is(tok::kw___try) && "Expected '__try'");
602 SourceLocation TryLoc = ConsumeToken();
603
604 if (Tok.isNot(K: tok::l_brace))
605 return StmtError(Diag(Tok, DiagID: diag::err_expected) << tok::l_brace);
606
607 StmtResult TryBlock(ParseCompoundStatement(
608 /*isStmtExpr=*/false,
609 ScopeFlags: Scope::DeclScope | Scope::CompoundStmtScope | Scope::SEHTryScope));
610 if (TryBlock.isInvalid())
611 return TryBlock;
612
613 StmtResult Handler;
614 if (Tok.is(K: tok::identifier) &&
615 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
616 SourceLocation Loc = ConsumeToken();
617 Handler = ParseSEHExceptBlock(Loc);
618 } else if (Tok.is(K: tok::kw___finally)) {
619 SourceLocation Loc = ConsumeToken();
620 Handler = ParseSEHFinallyBlock(Loc);
621 } else {
622 return StmtError(Diag(Tok, DiagID: diag::err_seh_expected_handler));
623 }
624
625 if(Handler.isInvalid())
626 return Handler;
627
628 return Actions.ActOnSEHTryBlock(IsCXXTry: false /* IsCXXTry */,
629 TryLoc,
630 TryBlock: TryBlock.get(),
631 Handler: Handler.get());
632}
633
634/// ParseSEHExceptBlock - Handle __except
635///
636/// seh-except-block:
637/// '__except' '(' seh-filter-expression ')' compound-statement
638///
639StmtResult 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(ExpectedTok: 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(ER: 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(ExpectedTok: tok::r_paren))
673 return StmtError();
674
675 if (Tok.isNot(K: tok::l_brace))
676 return StmtError(Diag(Tok, DiagID: diag::err_expected) << tok::l_brace);
677
678 StmtResult Block(ParseCompoundStatement());
679
680 if(Block.isInvalid())
681 return Block;
682
683 return Actions.ActOnSEHExceptBlock(Loc: ExceptLoc, FilterExpr: FilterExpr.get(), Block: Block.get());
684}
685
686/// ParseSEHFinallyBlock - Handle __finally
687///
688/// seh-finally-block:
689/// '__finally' compound-statement
690///
691StmtResult 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(K: tok::l_brace))
697 return StmtError(Diag(Tok, DiagID: 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(Loc: FinallyLoc, Block: Block.get());
709}
710
711/// Handle __leave
712///
713/// seh-leave-statement:
714/// '__leave' ';'
715///
716StmtResult Parser::ParseSEHLeaveStatement() {
717 SourceLocation LeaveLoc = ConsumeToken(); // eat the '__leave'.
718 return Actions.ActOnSEHLeaveStmt(Loc: LeaveLoc, CurScope: getCurScope());
719}
720
721static 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>(Val: SubStmt)) {
726 P.Diag(Loc: SubStmt->getBeginLoc(),
727 DiagID: 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///
742StmtResult 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(K: tok::kw___attribute)) {
763 ParsedAttributes TempAttrs(AttrFactory);
764 ParseGNUAttributes(Attrs&: 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(K: tok::semi))
774 Attrs.takeAllFrom(Other&: TempAttrs);
775 else {
776 StmtVector Stmts;
777 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
778 SubStmt = ParseStatementOrDeclarationAfterAttributes(
779 Stmts, StmtCtx, TrailingElseLoc: nullptr, CXX11Attrs&: EmptyCXX11Attrs, GNUAttrs&: TempAttrs);
780 if (!TempAttrs.empty() && !SubStmt.isInvalid())
781 SubStmt = Actions.ActOnAttributedStmt(AttrList: TempAttrs, SubStmt: SubStmt.get());
782 }
783 }
784
785 // The label may have no statement following it
786 if (SubStmt.isUnset() && Tok.is(K: tok::r_brace)) {
787 DiagnoseLabelAtEndOfCompoundStatement();
788 SubStmt = Actions.ActOnNullStmt(SemiLoc: ColonLoc);
789 }
790
791 // If we've not parsed a statement yet, parse one now.
792 if (!SubStmt.isInvalid() && !SubStmt.isUsable())
793 SubStmt = ParseStatement(TrailingElseLoc: 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(SemiLoc: ColonLoc);
798
799 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
800
801 LabelDecl *LD = Actions.LookupOrCreateLabel(II: IdentTok.getIdentifierInfo(),
802 IdentLoc: IdentTok.getLocation());
803 Actions.ProcessDeclAttributeList(S: Actions.CurScope, D: LD, AttrList: Attrs);
804 Attrs.clear();
805
806 return Actions.ActOnLabelStmt(IdentLoc: IdentTok.getLocation(), TheDecl: LD, ColonLoc,
807 SubStmt: SubStmt.get());
808}
809
810/// ParseCaseStatement
811/// labeled-statement:
812/// 'case' constant-expression ':' statement
813/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
814///
815StmtResult 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(K: tok::code_completion)) {
855 cutOffParsing();
856 Actions.CodeCompletion().CodeCompleteCase(S: 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(T1: tok::colon, T2: tok::r_brace, Flags: 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(Expected: tok::ellipsis, Loc&: DotDotDotLoc)) {
883 Diag(Loc: DotDotDotLoc, DiagID: diag::ext_gnu_case_range);
884 RHS = ParseCaseExpression(CaseLoc);
885 if (RHS.isInvalid()) {
886 if (!SkipUntil(T1: tok::colon, T2: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch))
887 return StmtError();
888 }
889 }
890
891 ColonProtection.restore();
892
893 if (TryConsumeToken(Expected: tok::colon, Loc&: ColonLoc)) {
894 } else if (TryConsumeToken(Expected: tok::semi, Loc&: ColonLoc) ||
895 TryConsumeToken(Expected: tok::coloncolon, Loc&: ColonLoc)) {
896 // Treat "case blah;" or "case blah::" as a typo for "case blah:".
897 Diag(Loc: ColonLoc, DiagID: diag::err_expected_after)
898 << "'case'" << tok::colon
899 << FixItHint::CreateReplacement(RemoveRange: ColonLoc, Code: ":");
900 } else {
901 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(Loc: PrevTokLocation);
902 Diag(Loc: ExpectedLoc, DiagID: diag::err_expected_after)
903 << "'case'" << tok::colon
904 << FixItHint::CreateInsertion(InsertionLoc: ExpectedLoc, Code: ":");
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(CaseStmt: DeepestParsedCaseStmt, SubStmt: Case.get());
925 DeepestParsedCaseStmt = NextDeepest;
926 }
927
928 // Handle all case statements.
929 } while (Tok.is(K: tok::kw_case));
930
931 // If we found a non-case statement, start by parsing it.
932 StmtResult SubStmt;
933
934 if (Tok.is(K: 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(SemiLoc: 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(SemiLoc: SourceLocation());
948 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
949 Actions.ActOnCaseStmtBody(CaseStmt: DeepestParsedCaseStmt, SubStmt: 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///
961StmtResult 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(Expected: tok::colon, Loc&: ColonLoc)) {
973 } else if (TryConsumeToken(Expected: tok::semi, Loc&: ColonLoc)) {
974 // Treat "default;" as a typo for "default:".
975 Diag(Loc: ColonLoc, DiagID: diag::err_expected_after)
976 << "'default'" << tok::colon
977 << FixItHint::CreateReplacement(RemoveRange: ColonLoc, Code: ":");
978 } else {
979 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(Loc: PrevTokLocation);
980 Diag(Loc: ExpectedLoc, DiagID: diag::err_expected_after)
981 << "'default'" << tok::colon
982 << FixItHint::CreateInsertion(InsertionLoc: ExpectedLoc, Code: ":");
983 ColonLoc = ExpectedLoc;
984 }
985
986 StmtResult SubStmt;
987
988 if (Tok.is(K: 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(SemiLoc: 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(SemiLoc: ColonLoc);
1000
1001 DiagnoseLabelFollowedByDecl(P&: *this, SubStmt: SubStmt.get());
1002 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
1003 SubStmt: SubStmt.get(), CurScope: getCurScope());
1004}
1005
1006StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
1007 return ParseCompoundStatement(isStmtExpr,
1008 ScopeFlags: 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///
1033StmtResult 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.
1048void 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
1115void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1116 if (getLangOpts().CPlusPlus) {
1117 Diag(Tok, DiagID: 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, DiagID: 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.
1129bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1130 if (!Tok.is(K: tok::semi))
1131 return false;
1132
1133 SourceLocation StartLoc = Tok.getLocation();
1134 SourceLocation EndLoc;
1135
1136 while (Tok.is(K: 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, StmtCtx: ParsedStmtContext::SubStmt);
1143 if (R.isUsable())
1144 Stmts.push_back(Elt: R.get());
1145 }
1146
1147 // Did not consume any extra semi.
1148 if (EndLoc.isInvalid())
1149 return false;
1150
1151 Diag(Loc: StartLoc, DiagID: diag::warn_null_statement)
1152 << FixItHint::CreateRemoval(RemoveRange: SourceRange(StartLoc, EndLoc));
1153 return true;
1154}
1155
1156StmtResult 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(N: LookAhead).is(K: 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(N: LookAhead).is(K: tok::r_brace) &&
1168 GetLookAheadToken(N: LookAhead + 1).is(K: tok::r_paren);
1169 }
1170
1171 if (IsStmtExprResult)
1172 E = Actions.ActOnStmtExprResult(E);
1173 return Actions.ActOnExprStmt(Arg: 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.
1180StmtResult 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(K: tok::kw___label__)) {
1205 SourceLocation LabelLoc = ConsumeToken();
1206
1207 SmallVector<Decl *, 8> DeclsInGroup;
1208 while (true) {
1209 if (Tok.isNot(K: tok::identifier)) {
1210 Diag(Tok, DiagID: diag::err_expected) << tok::identifier;
1211 break;
1212 }
1213
1214 IdentifierInfo *II = Tok.getIdentifierInfo();
1215 SourceLocation IdLoc = ConsumeToken();
1216 DeclsInGroup.push_back(Elt: Actions.LookupOrCreateLabel(II, IdentLoc: IdLoc, GnuLabelLoc: LabelLoc));
1217
1218 if (!TryConsumeToken(Expected: tok::comma))
1219 break;
1220 }
1221
1222 DeclSpec DS(AttrFactory);
1223 DeclGroupPtrTy Res =
1224 Actions.FinalizeDeclaratorGroup(S: getCurScope(), DS, Group: DeclsInGroup);
1225 StmtResult R = Actions.ActOnDeclStmt(Decl: Res, StartLoc: LabelLoc, EndLoc: Tok.getLocation());
1226
1227 ExpectAndConsumeSemi(DiagID: diag::err_expected_semi_declaration);
1228 if (R.isUsable())
1229 Stmts.push_back(Elt: R.get());
1230 }
1231
1232 ParsedStmtContext SubStmtCtx =
1233 ParsedStmtContext::Compound |
1234 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1235
1236 while (!tryParseMisplacedModuleImport() && Tok.isNot(K: tok::r_brace) &&
1237 Tok.isNot(K: tok::eof)) {
1238 if (Tok.is(K: tok::annot_pragma_unused)) {
1239 HandlePragmaUnused();
1240 continue;
1241 }
1242
1243 if (ConsumeNullStmt(Stmts))
1244 continue;
1245
1246 StmtResult R;
1247 if (Tok.isNot(K: tok::kw___extension__)) {
1248 R = ParseStatementOrDeclaration(Stmts, StmtCtx: 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(K: tok::kw___extension__))
1256 ConsumeToken();
1257
1258 ParsedAttributes attrs(AttrFactory);
1259 MaybeParseCXX11Attributes(Attrs&: attrs, /*MightBeObjCMessageSend*/ OuterMightBeMessageSend: 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(Context: DeclaratorContext::Block, DeclEnd,
1270 DeclAttrs&: attrs, DeclSpecAttrs);
1271 R = Actions.ActOnDeclStmt(Decl: Res, StartLoc: DeclStart, EndLoc: DeclEnd);
1272 } else {
1273 // Otherwise this was a unary __extension__ marker.
1274 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1275
1276 if (Res.isInvalid()) {
1277 SkipUntil(T: 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(DiagID: diag::err_expected_semi_after_expr);
1284 R = handleExprStmt(E: Res, StmtCtx: SubStmtCtx);
1285 if (R.isUsable())
1286 R = Actions.ActOnAttributedStmt(AttrList: attrs, SubStmt: R.get());
1287 }
1288 }
1289
1290 if (R.isUsable())
1291 Stmts.push_back(Elt: 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(Loc: Tok.getLocation(),
1302 DiagID: 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(K: tok::r_paren))
1311 checkCompoundToken(FirstTokLoc: CloseLoc, FirstTokKind: tok::r_brace, Op: 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(L: T.getOpenLocation(), R: CloseLoc,
1321 Elts: 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.
1338bool 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, MissingOK: 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(S: getCurScope(), Loc, SubExpr: 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(K: tok::r_paren)) {
1365 SkipUntil(T: 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(K: tok::r_paren))
1369 return true;
1370 }
1371
1372 if (Cond.isInvalid()) {
1373 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1374 Begin: Start, End: Tok.getLocation() == Start ? Start : PrevTokLocation, SubExprs: {},
1375 T: Actions.PreferredConditionType(K: CK));
1376 if (!CondExpr.isInvalid())
1377 Cond = Actions.ActOnCondition(S: getCurScope(), Loc, SubExpr: 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(K: tok::r_paren)) {
1390 Diag(Tok, DiagID: diag::err_extraneous_rparen_in_condition)
1391 << FixItHint::CreateRemoval(RemoveRange: Tok.getLocation());
1392 ConsumeParen();
1393 }
1394
1395 return false;
1396}
1397
1398namespace {
1399
1400enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1401
1402struct MisleadingIndentationChecker {
1403 Parser &P;
1404 SourceLocation StmtLoc;
1405 SourceLocation PrevLoc;
1406 unsigned NumDirectives;
1407 MisleadingStatementKind Kind;
1408 bool ShouldSkip;
1409 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(K: 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.
1424 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(FID: FIDAndOffset.first, Invalid: &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
1457 void Check() {
1458 Token Tok = P.getCurToken();
1459 if (P.getActions().getDiagnostics().isIgnored(
1460 DiagID: diag::warn_misleading_indentation, Loc: Tok.getLocation()) ||
1461 ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||
1462 Tok.isOneOf(K1: tok::semi, K2: 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, Loc: PrevLoc);
1474 unsigned CurColNum = getVisualIndentation(SM, Loc: Tok.getLocation());
1475 unsigned StmtColNum = getVisualIndentation(SM, Loc: StmtLoc);
1476
1477 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1478 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1479 !Tok.isAtStartOfLine()) &&
1480 SM.getPresumedLineNumber(Loc: StmtLoc) !=
1481 SM.getPresumedLineNumber(Loc: Tok.getLocation()) &&
1482 (Tok.isNot(K: tok::identifier) ||
1483 P.getPreprocessor().LookAhead(N: 0).isNot(K: tok::colon))) {
1484 P.Diag(Loc: Tok.getLocation(), DiagID: diag::warn_misleading_indentation) << Kind;
1485 P.Diag(Loc: StmtLoc, DiagID: 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///
1501StmtResult 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(K: tok::kw_constexpr)) {
1511 Diag(Tok, DiagID: getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
1512 : diag::ext_constexpr_if);
1513 IsConstexpr = true;
1514 ConsumeToken();
1515 } else {
1516 if (Tok.is(K: tok::exclaim)) {
1517 NotLocation = ConsumeToken();
1518 }
1519
1520 if (Tok.is(K: tok::kw_consteval)) {
1521 Diag(Tok, DiagID: getLangOpts().CPlusPlus23 ? diag::warn_cxx20_compat_consteval_if
1522 : diag::ext_consteval_if);
1523 IsConsteval = true;
1524 ConstevalLoc = ConsumeToken();
1525 }
1526 }
1527 if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(K: tok::l_paren))) {
1528 Diag(Tok, DiagID: diag::err_expected_lparen_after) << "if";
1529 SkipUntil(T: tok::semi);
1530 return StmtError();
1531 }
1532
1533 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1534
1535 // C99 6.8.4p3 - In C99, the if statement is a block. This is not
1536 // the case for C90.
1537 //
1538 // C++ 6.4p3:
1539 // A name introduced by a declaration in a condition is in scope from its
1540 // point of declaration until the end of the substatements controlled by the
1541 // condition.
1542 // C++ 3.3.2p4:
1543 // Names declared in the for-init-statement, and in the condition of if,
1544 // while, for, and switch statements are local to the if, while, for, or
1545 // switch statement (including the controlled statement).
1546 //
1547 ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
1548
1549 // Parse the condition.
1550 StmtResult InitStmt;
1551 Sema::ConditionResult Cond;
1552 SourceLocation LParen;
1553 SourceLocation RParen;
1554 std::optional<bool> ConstexprCondition;
1555 if (!IsConsteval) {
1556
1557 if (ParseParenExprOrCondition(InitStmt: &InitStmt, Cond, Loc: IfLoc,
1558 CK: IsConstexpr ? Sema::ConditionKind::ConstexprIf
1559 : Sema::ConditionKind::Boolean,
1560 LParenLoc&: LParen, RParenLoc&: RParen))
1561 return StmtError();
1562
1563 if (IsConstexpr)
1564 ConstexprCondition = Cond.getKnownValue();
1565 }
1566
1567 bool IsBracedThen = Tok.is(K: tok::l_brace);
1568
1569 // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
1570 // there is no compound stmt. C90 does not have this clause. We only do this
1571 // if the body isn't a compound statement to avoid push/pop in common cases.
1572 //
1573 // C++ 6.4p1:
1574 // The substatement in a selection-statement (each substatement, in the else
1575 // form of the if statement) implicitly defines a local scope.
1576 //
1577 // For C++ we create a scope for the condition and a new scope for
1578 // substatements because:
1579 // -When the 'then' scope exits, we want the condition declaration to still be
1580 // active for the 'else' scope too.
1581 // -Sema will detect name clashes by considering declarations of a
1582 // 'ControlScope' as part of its direct subscope.
1583 // -If we wanted the condition and substatement to be in the same scope, we
1584 // would have to notify ParseStatement not to create a new scope. It's
1585 // simpler to let it create a new scope.
1586 //
1587 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
1588
1589 MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
1590
1591 // Read the 'then' stmt.
1592 SourceLocation ThenStmtLoc = Tok.getLocation();
1593
1594 SourceLocation InnerStatementTrailingElseLoc;
1595 StmtResult ThenStmt;
1596 {
1597 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1598 Sema::ExpressionEvaluationContext Context =
1599 Sema::ExpressionEvaluationContext::DiscardedStatement;
1600 if (NotLocation.isInvalid() && IsConsteval) {
1601 Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
1602 ShouldEnter = true;
1603 }
1604
1605 EnterExpressionEvaluationContext PotentiallyDiscarded(
1606 Actions, Context, nullptr,
1607 Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
1608 ThenStmt = ParseStatement(TrailingElseLoc: &InnerStatementTrailingElseLoc);
1609 }
1610
1611 if (Tok.isNot(K: tok::kw_else))
1612 MIChecker.Check();
1613
1614 // Pop the 'if' scope if needed.
1615 InnerScope.Exit();
1616
1617 // If it has an else, parse it.
1618 SourceLocation ElseLoc;
1619 SourceLocation ElseStmtLoc;
1620 StmtResult ElseStmt;
1621
1622 if (Tok.is(K: tok::kw_else)) {
1623 if (TrailingElseLoc)
1624 *TrailingElseLoc = Tok.getLocation();
1625
1626 ElseLoc = ConsumeToken();
1627 ElseStmtLoc = Tok.getLocation();
1628
1629 // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
1630 // there is no compound stmt. C90 does not have this clause. We only do
1631 // this if the body isn't a compound statement to avoid push/pop in common
1632 // cases.
1633 //
1634 // C++ 6.4p1:
1635 // The substatement in a selection-statement (each substatement, in the else
1636 // form of the if statement) implicitly defines a local scope.
1637 //
1638 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX,
1639 Tok.is(K: tok::l_brace));
1640
1641 MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);
1642 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1643 Sema::ExpressionEvaluationContext Context =
1644 Sema::ExpressionEvaluationContext::DiscardedStatement;
1645 if (NotLocation.isValid() && IsConsteval) {
1646 Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
1647 ShouldEnter = true;
1648 }
1649
1650 EnterExpressionEvaluationContext PotentiallyDiscarded(
1651 Actions, Context, nullptr,
1652 Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
1653 ElseStmt = ParseStatement();
1654
1655 if (ElseStmt.isUsable())
1656 MIChecker.Check();
1657
1658 // Pop the 'else' scope if needed.
1659 InnerScope.Exit();
1660 } else if (Tok.is(K: tok::code_completion)) {
1661 cutOffParsing();
1662 Actions.CodeCompletion().CodeCompleteAfterIf(S: getCurScope(), IsBracedThen);
1663 return StmtError();
1664 } else if (InnerStatementTrailingElseLoc.isValid()) {
1665 Diag(Loc: InnerStatementTrailingElseLoc, DiagID: diag::warn_dangling_else);
1666 }
1667
1668 IfScope.Exit();
1669
1670 // If the then or else stmt is invalid and the other is valid (and present),
1671 // turn the invalid one into a null stmt to avoid dropping the other
1672 // part. If both are invalid, return error.
1673 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1674 (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
1675 (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
1676 // Both invalid, or one is invalid and other is non-present: return error.
1677 return StmtError();
1678 }
1679
1680 if (IsConsteval) {
1681 auto IsCompoundStatement = [](const Stmt *S) {
1682 if (const auto *Outer = dyn_cast_if_present<AttributedStmt>(Val: S))
1683 S = Outer->getSubStmt();
1684 return isa_and_nonnull<clang::CompoundStmt>(Val: S);
1685 };
1686
1687 if (!IsCompoundStatement(ThenStmt.get())) {
1688 Diag(Loc: ConstevalLoc, DiagID: diag::err_expected_after) << "consteval"
1689 << "{";
1690 return StmtError();
1691 }
1692 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1693 Diag(Loc: ElseLoc, DiagID: diag::err_expected_after) << "else"
1694 << "{";
1695 return StmtError();
1696 }
1697 }
1698
1699 // Now if either are invalid, replace with a ';'.
1700 if (ThenStmt.isInvalid())
1701 ThenStmt = Actions.ActOnNullStmt(SemiLoc: ThenStmtLoc);
1702 if (ElseStmt.isInvalid())
1703 ElseStmt = Actions.ActOnNullStmt(SemiLoc: ElseStmtLoc);
1704
1705 IfStatementKind Kind = IfStatementKind::Ordinary;
1706 if (IsConstexpr)
1707 Kind = IfStatementKind::Constexpr;
1708 else if (IsConsteval)
1709 Kind = NotLocation.isValid() ? IfStatementKind::ConstevalNegated
1710 : IfStatementKind::ConstevalNonNegated;
1711
1712 return Actions.ActOnIfStmt(IfLoc, StatementKind: Kind, LParenLoc: LParen, InitStmt: InitStmt.get(), Cond, RParenLoc: RParen,
1713 ThenVal: ThenStmt.get(), ElseLoc, ElseVal: ElseStmt.get());
1714}
1715
1716/// ParseSwitchStatement
1717/// switch-statement:
1718/// 'switch' '(' expression ')' statement
1719/// [C++] 'switch' '(' condition ')' statement
1720StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
1721 assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
1722 SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
1723
1724 if (Tok.isNot(K: tok::l_paren)) {
1725 Diag(Tok, DiagID: diag::err_expected_lparen_after) << "switch";
1726 SkipUntil(T: tok::semi);
1727 return StmtError();
1728 }
1729
1730 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1731
1732 // C99 6.8.4p3 - In C99, the switch statement is a block. This is
1733 // not the case for C90. Start the switch scope.
1734 //
1735 // C++ 6.4p3:
1736 // A name introduced by a declaration in a condition is in scope from its
1737 // point of declaration until the end of the substatements controlled by the
1738 // condition.
1739 // C++ 3.3.2p4:
1740 // Names declared in the for-init-statement, and in the condition of if,
1741 // while, for, and switch statements are local to the if, while, for, or
1742 // switch statement (including the controlled statement).
1743 //
1744 unsigned ScopeFlags = Scope::SwitchScope;
1745 if (C99orCXX)
1746 ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
1747 ParseScope SwitchScope(this, ScopeFlags);
1748
1749 // Parse the condition.
1750 StmtResult InitStmt;
1751 Sema::ConditionResult Cond;
1752 SourceLocation LParen;
1753 SourceLocation RParen;
1754 if (ParseParenExprOrCondition(InitStmt: &InitStmt, Cond, Loc: SwitchLoc,
1755 CK: Sema::ConditionKind::Switch, LParenLoc&: LParen, RParenLoc&: RParen))
1756 return StmtError();
1757
1758 StmtResult Switch = Actions.ActOnStartOfSwitchStmt(
1759 SwitchLoc, LParenLoc: LParen, InitStmt: InitStmt.get(), Cond, RParenLoc: RParen);
1760
1761 if (Switch.isInvalid()) {
1762 // Skip the switch body.
1763 // FIXME: This is not optimal recovery, but parsing the body is more
1764 // dangerous due to the presence of case and default statements, which
1765 // will have no place to connect back with the switch.
1766 if (Tok.is(K: tok::l_brace)) {
1767 ConsumeBrace();
1768 SkipUntil(T: tok::r_brace);
1769 } else
1770 SkipUntil(T: tok::semi);
1771 return Switch;
1772 }
1773
1774 // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
1775 // there is no compound stmt. C90 does not have this clause. We only do this
1776 // if the body isn't a compound statement to avoid push/pop in common cases.
1777 //
1778 // C++ 6.4p1:
1779 // The substatement in a selection-statement (each substatement, in the else
1780 // form of the if statement) implicitly defines a local scope.
1781 //
1782 // See comments in ParseIfStatement for why we create a scope for the
1783 // condition and a new scope for substatement in C++.
1784 //
1785 getCurScope()->AddFlags(Flags: Scope::BreakScope);
1786 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1787
1788 // We have incremented the mangling number for the SwitchScope and the
1789 // InnerScope, which is one too many.
1790 if (C99orCXX)
1791 getCurScope()->decrementMSManglingNumber();
1792
1793 // Read the body statement.
1794 StmtResult Body(ParseStatement(TrailingElseLoc));
1795
1796 // Pop the scopes.
1797 InnerScope.Exit();
1798 SwitchScope.Exit();
1799
1800 return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch: Switch.get(), Body: Body.get());
1801}
1802
1803/// ParseWhileStatement
1804/// while-statement: [C99 6.8.5.1]
1805/// 'while' '(' expression ')' statement
1806/// [C++] 'while' '(' condition ')' statement
1807StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
1808 assert(Tok.is(tok::kw_while) && "Not a while stmt!");
1809 SourceLocation WhileLoc = Tok.getLocation();
1810 ConsumeToken(); // eat the 'while'.
1811
1812 if (Tok.isNot(K: tok::l_paren)) {
1813 Diag(Tok, DiagID: diag::err_expected_lparen_after) << "while";
1814 SkipUntil(T: tok::semi);
1815 return StmtError();
1816 }
1817
1818 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1819
1820 // C99 6.8.5p5 - In C99, the while statement is a block. This is not
1821 // the case for C90. Start the loop scope.
1822 //
1823 // C++ 6.4p3:
1824 // A name introduced by a declaration in a condition is in scope from its
1825 // point of declaration until the end of the substatements controlled by the
1826 // condition.
1827 // C++ 3.3.2p4:
1828 // Names declared in the for-init-statement, and in the condition of if,
1829 // while, for, and switch statements are local to the if, while, for, or
1830 // switch statement (including the controlled statement).
1831 //
1832 unsigned ScopeFlags;
1833 if (C99orCXX)
1834 ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
1835 Scope::DeclScope | Scope::ControlScope;
1836 else
1837 ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
1838 ParseScope WhileScope(this, ScopeFlags);
1839
1840 // Parse the condition.
1841 Sema::ConditionResult Cond;
1842 SourceLocation LParen;
1843 SourceLocation RParen;
1844 if (ParseParenExprOrCondition(InitStmt: nullptr, Cond, Loc: WhileLoc,
1845 CK: Sema::ConditionKind::Boolean, LParenLoc&: LParen, RParenLoc&: RParen))
1846 return StmtError();
1847
1848 // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
1849 // there is no compound stmt. C90 does not have this clause. We only do this
1850 // if the body isn't a compound statement to avoid push/pop in common cases.
1851 //
1852 // C++ 6.5p2:
1853 // The substatement in an iteration-statement implicitly defines a local scope
1854 // which is entered and exited each time through the loop.
1855 //
1856 // See comments in ParseIfStatement for why we create a scope for the
1857 // condition and a new scope for substatement in C++.
1858 //
1859 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1860
1861 MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);
1862
1863 // Read the body statement.
1864 StmtResult Body(ParseStatement(TrailingElseLoc));
1865
1866 if (Body.isUsable())
1867 MIChecker.Check();
1868 // Pop the body scope if needed.
1869 InnerScope.Exit();
1870 WhileScope.Exit();
1871
1872 if (Cond.isInvalid() || Body.isInvalid())
1873 return StmtError();
1874
1875 return Actions.ActOnWhileStmt(WhileLoc, LParenLoc: LParen, Cond, RParenLoc: RParen, Body: Body.get());
1876}
1877
1878/// ParseDoStatement
1879/// do-statement: [C99 6.8.5.2]
1880/// 'do' statement 'while' '(' expression ')' ';'
1881/// Note: this lets the caller parse the end ';'.
1882StmtResult Parser::ParseDoStatement() {
1883 assert(Tok.is(tok::kw_do) && "Not a do stmt!");
1884 SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
1885
1886 // C99 6.8.5p5 - In C99, the do statement is a block. This is not
1887 // the case for C90. Start the loop scope.
1888 unsigned ScopeFlags;
1889 if (getLangOpts().C99)
1890 ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
1891 else
1892 ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
1893
1894 ParseScope DoScope(this, ScopeFlags);
1895
1896 // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if
1897 // there is no compound stmt. C90 does not have this clause. We only do this
1898 // if the body isn't a compound statement to avoid push/pop in common cases.
1899 //
1900 // C++ 6.5p2:
1901 // The substatement in an iteration-statement implicitly defines a local scope
1902 // which is entered and exited each time through the loop.
1903 //
1904 bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1905 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(K: tok::l_brace));
1906
1907 // Read the body statement.
1908 StmtResult Body(ParseStatement());
1909
1910 // Pop the body scope if needed.
1911 InnerScope.Exit();
1912
1913 if (Tok.isNot(K: tok::kw_while)) {
1914 if (!Body.isInvalid()) {
1915 Diag(Tok, DiagID: diag::err_expected_while);
1916 Diag(Loc: DoLoc, DiagID: diag::note_matching) << "'do'";
1917 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
1918 }
1919 return StmtError();
1920 }
1921 SourceLocation WhileLoc = ConsumeToken();
1922
1923 if (Tok.isNot(K: tok::l_paren)) {
1924 Diag(Tok, DiagID: diag::err_expected_lparen_after) << "do/while";
1925 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
1926 return StmtError();
1927 }
1928
1929 // Parse the parenthesized expression.
1930 BalancedDelimiterTracker T(*this, tok::l_paren);
1931 T.consumeOpen();
1932
1933 // A do-while expression is not a condition, so can't have attributes.
1934 DiagnoseAndSkipCXX11Attributes();
1935
1936 SourceLocation Start = Tok.getLocation();
1937 ExprResult Cond = ParseExpression();
1938 // Correct the typos in condition before closing the scope.
1939 if (Cond.isUsable())
1940 Cond = Actions.CorrectDelayedTyposInExpr(ER: Cond, /*InitDecl=*/nullptr,
1941 /*RecoverUncorrectedTypos=*/true);
1942 else {
1943 if (!Tok.isOneOf(K1: tok::r_paren, Ks: tok::r_square, Ks: tok::r_brace))
1944 SkipUntil(T: tok::semi);
1945 Cond = Actions.CreateRecoveryExpr(
1946 Begin: Start, End: Start == Tok.getLocation() ? Start : PrevTokLocation, SubExprs: {},
1947 T: Actions.getASTContext().BoolTy);
1948 }
1949 T.consumeClose();
1950 DoScope.Exit();
1951
1952 if (Cond.isInvalid() || Body.isInvalid())
1953 return StmtError();
1954
1955 return Actions.ActOnDoStmt(DoLoc, Body: Body.get(), WhileLoc, CondLParen: T.getOpenLocation(),
1956 Cond: Cond.get(), CondRParen: T.getCloseLocation());
1957}
1958
1959bool Parser::isForRangeIdentifier() {
1960 assert(Tok.is(tok::identifier));
1961
1962 const Token &Next = NextToken();
1963 if (Next.is(K: tok::colon))
1964 return true;
1965
1966 if (Next.isOneOf(K1: tok::l_square, K2: tok::kw_alignas)) {
1967 TentativeParsingAction PA(*this);
1968 ConsumeToken();
1969 SkipCXX11Attributes();
1970 bool Result = Tok.is(K: tok::colon);
1971 PA.Revert();
1972 return Result;
1973 }
1974
1975 return false;
1976}
1977
1978/// ParseForStatement
1979/// for-statement: [C99 6.8.5.3]
1980/// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
1981/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
1982/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
1983/// [C++] statement
1984/// [C++0x] 'for'
1985/// 'co_await'[opt] [Coroutines]
1986/// '(' for-range-declaration ':' for-range-initializer ')'
1987/// statement
1988/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
1989/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
1990///
1991/// [C++] for-init-statement:
1992/// [C++] expression-statement
1993/// [C++] simple-declaration
1994/// [C++23] alias-declaration
1995///
1996/// [C++0x] for-range-declaration:
1997/// [C++0x] attribute-specifier-seq[opt] type-specifier-seq declarator
1998/// [C++0x] for-range-initializer:
1999/// [C++0x] expression
2000/// [C++0x] braced-init-list [TODO]
2001StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
2002 assert(Tok.is(tok::kw_for) && "Not a for stmt!");
2003 SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
2004
2005 SourceLocation CoawaitLoc;
2006 if (Tok.is(K: tok::kw_co_await))
2007 CoawaitLoc = ConsumeToken();
2008
2009 if (Tok.isNot(K: tok::l_paren)) {
2010 Diag(Tok, DiagID: diag::err_expected_lparen_after) << "for";
2011 SkipUntil(T: tok::semi);
2012 return StmtError();
2013 }
2014
2015 bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||
2016 getLangOpts().ObjC;
2017
2018 // C99 6.8.5p5 - In C99, the for statement is a block. This is not
2019 // the case for C90. Start the loop scope.
2020 //
2021 // C++ 6.4p3:
2022 // A name introduced by a declaration in a condition is in scope from its
2023 // point of declaration until the end of the substatements controlled by the
2024 // condition.
2025 // C++ 3.3.2p4:
2026 // Names declared in the for-init-statement, and in the condition of if,
2027 // while, for, and switch statements are local to the if, while, for, or
2028 // switch statement (including the controlled statement).
2029 // C++ 6.5.3p1:
2030 // Names declared in the for-init-statement are in the same declarative-region
2031 // as those declared in the condition.
2032 //
2033 unsigned ScopeFlags = 0;
2034 if (C99orCXXorObjC)
2035 ScopeFlags = Scope::DeclScope | Scope::ControlScope;
2036
2037 ParseScope ForScope(this, ScopeFlags);
2038
2039 BalancedDelimiterTracker T(*this, tok::l_paren);
2040 T.consumeOpen();
2041
2042 ExprResult Value;
2043
2044 bool ForEach = false;
2045 StmtResult FirstPart;
2046 Sema::ConditionResult SecondPart;
2047 ExprResult Collection;
2048 ForRangeInfo ForRangeInfo;
2049 FullExprArg ThirdPart(Actions);
2050
2051 if (Tok.is(K: tok::code_completion)) {
2052 cutOffParsing();
2053 Actions.CodeCompletion().CodeCompleteOrdinaryName(
2054 S: getCurScope(), CompletionContext: C99orCXXorObjC ? SemaCodeCompletion::PCC_ForInit
2055 : SemaCodeCompletion::PCC_Expression);
2056 return StmtError();
2057 }
2058
2059 ParsedAttributes attrs(AttrFactory);
2060 MaybeParseCXX11Attributes(Attrs&: attrs);
2061
2062 SourceLocation EmptyInitStmtSemiLoc;
2063
2064 // Parse the first part of the for specifier.
2065 if (Tok.is(K: tok::semi)) { // for (;
2066 ProhibitAttributes(Attrs&: attrs);
2067 // no first part, eat the ';'.
2068 SourceLocation SemiLoc = Tok.getLocation();
2069 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID())
2070 EmptyInitStmtSemiLoc = SemiLoc;
2071 ConsumeToken();
2072 } else if (getLangOpts().CPlusPlus && Tok.is(K: tok::identifier) &&
2073 isForRangeIdentifier()) {
2074 ProhibitAttributes(Attrs&: attrs);
2075 IdentifierInfo *Name = Tok.getIdentifierInfo();
2076 SourceLocation Loc = ConsumeToken();
2077 MaybeParseCXX11Attributes(Attrs&: attrs);
2078
2079 ForRangeInfo.ColonLoc = ConsumeToken();
2080 if (Tok.is(K: tok::l_brace))
2081 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2082 else
2083 ForRangeInfo.RangeExpr = ParseExpression();
2084
2085 Diag(Loc, DiagID: diag::err_for_range_identifier)
2086 << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus17)
2087 ? FixItHint::CreateInsertion(InsertionLoc: Loc, Code: "auto &&")
2088 : FixItHint());
2089
2090 ForRangeInfo.LoopVar =
2091 Actions.ActOnCXXForRangeIdentifier(S: getCurScope(), IdentLoc: Loc, Ident: Name, Attrs&: attrs);
2092 } else if (isForInitDeclaration()) { // for (int X = 4;
2093 ParenBraceBracketBalancer BalancerRAIIObj(*this);
2094
2095 // Parse declaration, which eats the ';'.
2096 if (!C99orCXXorObjC) { // Use of C99-style for loops in C90 mode?
2097 Diag(Tok, DiagID: diag::ext_c99_variable_decl_in_for_loop);
2098 Diag(Tok, DiagID: diag::warn_gcc_variable_decl_in_for_loop);
2099 }
2100 DeclGroupPtrTy DG;
2101 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2102 if (Tok.is(K: tok::kw_using)) {
2103 DG = ParseAliasDeclarationInInitStatement(Context: DeclaratorContext::ForInit,
2104 Attrs&: attrs);
2105 FirstPart = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: Tok.getLocation());
2106 } else {
2107 // In C++0x, "for (T NS:a" might not be a typo for ::
2108 bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
2109 ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
2110 ParsedAttributes DeclSpecAttrs(AttrFactory);
2111 DG = ParseSimpleDeclaration(
2112 Context: DeclaratorContext::ForInit, DeclEnd, DeclAttrs&: attrs, DeclSpecAttrs, RequireSemi: false,
2113 FRI: MightBeForRangeStmt ? &ForRangeInfo : nullptr);
2114 FirstPart = Actions.ActOnDeclStmt(Decl: DG, StartLoc: DeclStart, EndLoc: Tok.getLocation());
2115 if (ForRangeInfo.ParsedForRangeDecl()) {
2116 Diag(Loc: ForRangeInfo.ColonLoc, DiagID: getLangOpts().CPlusPlus11
2117 ? diag::warn_cxx98_compat_for_range
2118 : diag::ext_for_range);
2119 ForRangeInfo.LoopVar = FirstPart;
2120 FirstPart = StmtResult();
2121 } else if (Tok.is(K: tok::semi)) { // for (int x = 4;
2122 ConsumeToken();
2123 } else if ((ForEach = isTokIdentifier_in())) {
2124 Actions.ActOnForEachDeclStmt(Decl: DG);
2125 // ObjC: for (id x in expr)
2126 ConsumeToken(); // consume 'in'
2127
2128 if (Tok.is(K: tok::code_completion)) {
2129 cutOffParsing();
2130 Actions.CodeCompletion().CodeCompleteObjCForCollection(S: getCurScope(),
2131 IterationVar: DG);
2132 return StmtError();
2133 }
2134 Collection = ParseExpression();
2135 } else {
2136 Diag(Tok, DiagID: diag::err_expected_semi_for);
2137 }
2138 }
2139 } else {
2140 ProhibitAttributes(Attrs&: attrs);
2141 Value = Actions.CorrectDelayedTyposInExpr(ER: ParseExpression());
2142
2143 ForEach = isTokIdentifier_in();
2144
2145 // Turn the expression into a stmt.
2146 if (!Value.isInvalid()) {
2147 if (ForEach)
2148 FirstPart = Actions.ActOnForEachLValueExpr(E: Value.get());
2149 else {
2150 // We already know this is not an init-statement within a for loop, so
2151 // if we are parsing a C++11 range-based for loop, we should treat this
2152 // expression statement as being a discarded value expression because
2153 // we will err below. This way we do not warn on an unused expression
2154 // that was an error in the first place, like with: for (expr : expr);
2155 bool IsRangeBasedFor =
2156 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(K: tok::colon);
2157 FirstPart = Actions.ActOnExprStmt(Arg: Value, DiscardedValue: !IsRangeBasedFor);
2158 }
2159 }
2160
2161 if (Tok.is(K: tok::semi)) {
2162 ConsumeToken();
2163 } else if (ForEach) {
2164 ConsumeToken(); // consume 'in'
2165
2166 if (Tok.is(K: tok::code_completion)) {
2167 cutOffParsing();
2168 Actions.CodeCompletion().CodeCompleteObjCForCollection(S: getCurScope(),
2169 IterationVar: nullptr);
2170 return StmtError();
2171 }
2172 Collection = ParseExpression();
2173 } else if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::colon) && FirstPart.get()) {
2174 // User tried to write the reasonable, but ill-formed, for-range-statement
2175 // for (expr : expr) { ... }
2176 Diag(Tok, DiagID: diag::err_for_range_expected_decl)
2177 << FirstPart.get()->getSourceRange();
2178 SkipUntil(T: tok::r_paren, Flags: StopBeforeMatch);
2179 SecondPart = Sema::ConditionError();
2180 } else {
2181 if (!Value.isInvalid()) {
2182 Diag(Tok, DiagID: diag::err_expected_semi_for);
2183 } else {
2184 // Skip until semicolon or rparen, don't consume it.
2185 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
2186 if (Tok.is(K: tok::semi))
2187 ConsumeToken();
2188 }
2189 }
2190 }
2191
2192 // Parse the second part of the for specifier.
2193 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2194 !SecondPart.isInvalid()) {
2195 // Parse the second part of the for specifier.
2196 if (Tok.is(K: tok::semi)) { // for (...;;
2197 // no second part.
2198 } else if (Tok.is(K: tok::r_paren)) {
2199 // missing both semicolons.
2200 } else {
2201 if (getLangOpts().CPlusPlus) {
2202 // C++2a: We've parsed an init-statement; we might have a
2203 // for-range-declaration next.
2204 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2205 ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
2206 SourceLocation SecondPartStart = Tok.getLocation();
2207 Sema::ConditionKind CK = Sema::ConditionKind::Boolean;
2208 SecondPart = ParseCXXCondition(
2209 /*InitStmt=*/nullptr, Loc: ForLoc, CK,
2210 // FIXME: recovery if we don't see another semi!
2211 /*MissingOK=*/true, FRI: MightBeForRangeStmt ? &ForRangeInfo : nullptr,
2212 /*EnterForConditionScope=*/true);
2213
2214 if (ForRangeInfo.ParsedForRangeDecl()) {
2215 Diag(Loc: FirstPart.get() ? FirstPart.get()->getBeginLoc()
2216 : ForRangeInfo.ColonLoc,
2217 DiagID: getLangOpts().CPlusPlus20
2218 ? diag::warn_cxx17_compat_for_range_init_stmt
2219 : diag::ext_for_range_init_stmt)
2220 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2221 : SourceRange());
2222 if (EmptyInitStmtSemiLoc.isValid()) {
2223 Diag(Loc: EmptyInitStmtSemiLoc, DiagID: diag::warn_empty_init_statement)
2224 << /*for-loop*/ 2
2225 << FixItHint::CreateRemoval(RemoveRange: EmptyInitStmtSemiLoc);
2226 }
2227 }
2228
2229 if (SecondPart.isInvalid()) {
2230 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2231 Begin: SecondPartStart,
2232 End: Tok.getLocation() == SecondPartStart ? SecondPartStart
2233 : PrevTokLocation,
2234 SubExprs: {}, T: Actions.PreferredConditionType(K: CK));
2235 if (!CondExpr.isInvalid())
2236 SecondPart = Actions.ActOnCondition(S: getCurScope(), Loc: ForLoc,
2237 SubExpr: CondExpr.get(), CK,
2238 /*MissingOK=*/false);
2239 }
2240
2241 } else {
2242 // We permit 'continue' and 'break' in the condition of a for loop.
2243 getCurScope()->AddFlags(Flags: Scope::BreakScope | Scope::ContinueScope);
2244
2245 ExprResult SecondExpr = ParseExpression();
2246 if (SecondExpr.isInvalid())
2247 SecondPart = Sema::ConditionError();
2248 else
2249 SecondPart = Actions.ActOnCondition(
2250 S: getCurScope(), Loc: ForLoc, SubExpr: SecondExpr.get(),
2251 CK: Sema::ConditionKind::Boolean, /*MissingOK=*/true);
2252 }
2253 }
2254 }
2255
2256 // Enter a break / continue scope, if we didn't already enter one while
2257 // parsing the second part.
2258 if (!getCurScope()->isContinueScope())
2259 getCurScope()->AddFlags(Flags: Scope::BreakScope | Scope::ContinueScope);
2260
2261 // Parse the third part of the for statement.
2262 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2263 if (Tok.isNot(K: tok::semi)) {
2264 if (!SecondPart.isInvalid())
2265 Diag(Tok, DiagID: diag::err_expected_semi_for);
2266 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
2267 }
2268
2269 if (Tok.is(K: tok::semi)) {
2270 ConsumeToken();
2271 }
2272
2273 if (Tok.isNot(K: tok::r_paren)) { // for (...;...;)
2274 ExprResult Third = ParseExpression();
2275 // FIXME: The C++11 standard doesn't actually say that this is a
2276 // discarded-value expression, but it clearly should be.
2277 ThirdPart = Actions.MakeFullDiscardedValueExpr(Arg: Third.get());
2278 }
2279 }
2280 // Match the ')'.
2281 T.consumeClose();
2282
2283 // C++ Coroutines [stmt.iter]:
2284 // 'co_await' can only be used for a range-based for statement.
2285 if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2286 Diag(Loc: CoawaitLoc, DiagID: diag::err_for_co_await_not_range_for);
2287 CoawaitLoc = SourceLocation();
2288 }
2289
2290 if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20)
2291 Diag(Loc: CoawaitLoc, DiagID: diag::warn_deprecated_for_co_await);
2292
2293 // We need to perform most of the semantic analysis for a C++0x for-range
2294 // statememt before parsing the body, in order to be able to deduce the type
2295 // of an auto-typed loop variable.
2296 StmtResult ForRangeStmt;
2297 StmtResult ForEachStmt;
2298
2299 if (ForRangeInfo.ParsedForRangeDecl()) {
2300 ExprResult CorrectedRange =
2301 Actions.CorrectDelayedTyposInExpr(E: ForRangeInfo.RangeExpr.get());
2302 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2303 S: getCurScope(), ForLoc, CoawaitLoc, InitStmt: FirstPart.get(),
2304 LoopVar: ForRangeInfo.LoopVar.get(), ColonLoc: ForRangeInfo.ColonLoc, Collection: CorrectedRange.get(),
2305 RParenLoc: T.getCloseLocation(), Kind: Sema::BFRK_Build,
2306 LifetimeExtendTemps: ForRangeInfo.LifetimeExtendTemps);
2307 } else if (ForEach) {
2308 // Similarly, we need to do the semantic analysis for a for-range
2309 // statement immediately in order to close over temporaries correctly.
2310 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2311 ForColLoc: ForLoc, First: FirstPart.get(), collection: Collection.get(), RParenLoc: T.getCloseLocation());
2312 } else {
2313 // In OpenMP loop region loop control variable must be captured and be
2314 // private. Perform analysis of first part (if any).
2315 if (getLangOpts().OpenMP && FirstPart.isUsable()) {
2316 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, Init: FirstPart.get());
2317 }
2318 }
2319
2320 // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
2321 // there is no compound stmt. C90 does not have this clause. We only do this
2322 // if the body isn't a compound statement to avoid push/pop in common cases.
2323 //
2324 // C++ 6.5p2:
2325 // The substatement in an iteration-statement implicitly defines a local scope
2326 // which is entered and exited each time through the loop.
2327 //
2328 // See comments in ParseIfStatement for why we create a scope for
2329 // for-init-statement/condition and a new scope for substatement in C++.
2330 //
2331 ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
2332 Tok.is(K: tok::l_brace));
2333
2334 // The body of the for loop has the same local mangling number as the
2335 // for-init-statement.
2336 // It will only be incremented if the body contains other things that would
2337 // normally increment the mangling number (like a compound statement).
2338 if (C99orCXXorObjC)
2339 getCurScope()->decrementMSManglingNumber();
2340
2341 MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);
2342
2343 // Read the body statement.
2344 StmtResult Body(ParseStatement(TrailingElseLoc));
2345
2346 if (Body.isUsable())
2347 MIChecker.Check();
2348
2349 // Pop the body scope if needed.
2350 InnerScope.Exit();
2351
2352 // Leave the for-scope.
2353 ForScope.Exit();
2354
2355 if (Body.isInvalid())
2356 return StmtError();
2357
2358 if (ForEach)
2359 return Actions.ObjC().FinishObjCForCollectionStmt(ForCollection: ForEachStmt.get(),
2360 Body: Body.get());
2361
2362 if (ForRangeInfo.ParsedForRangeDecl())
2363 return Actions.FinishCXXForRangeStmt(ForRange: ForRangeStmt.get(), Body: Body.get());
2364
2365 return Actions.ActOnForStmt(ForLoc, LParenLoc: T.getOpenLocation(), First: FirstPart.get(),
2366 Second: SecondPart, Third: ThirdPart, RParenLoc: T.getCloseLocation(),
2367 Body: Body.get());
2368}
2369
2370/// ParseGotoStatement
2371/// jump-statement:
2372/// 'goto' identifier ';'
2373/// [GNU] 'goto' '*' expression ';'
2374///
2375/// Note: this lets the caller parse the end ';'.
2376///
2377StmtResult Parser::ParseGotoStatement() {
2378 assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
2379 SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
2380
2381 StmtResult Res;
2382 if (Tok.is(K: tok::identifier)) {
2383 LabelDecl *LD = Actions.LookupOrCreateLabel(II: Tok.getIdentifierInfo(),
2384 IdentLoc: Tok.getLocation());
2385 Res = Actions.ActOnGotoStmt(GotoLoc, LabelLoc: Tok.getLocation(), TheDecl: LD);
2386 ConsumeToken();
2387 } else if (Tok.is(K: tok::star)) {
2388 // GNU indirect goto extension.
2389 Diag(Tok, DiagID: diag::ext_gnu_indirect_goto);
2390 SourceLocation StarLoc = ConsumeToken();
2391 ExprResult R(ParseExpression());
2392 if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
2393 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
2394 return StmtError();
2395 }
2396 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, DestExp: R.get());
2397 } else {
2398 Diag(Tok, DiagID: diag::err_expected) << tok::identifier;
2399 return StmtError();
2400 }
2401
2402 return Res;
2403}
2404
2405/// ParseContinueStatement
2406/// jump-statement:
2407/// 'continue' ';'
2408///
2409/// Note: this lets the caller parse the end ';'.
2410///
2411StmtResult Parser::ParseContinueStatement() {
2412 SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
2413 return Actions.ActOnContinueStmt(ContinueLoc, CurScope: getCurScope());
2414}
2415
2416/// ParseBreakStatement
2417/// jump-statement:
2418/// 'break' ';'
2419///
2420/// Note: this lets the caller parse the end ';'.
2421///
2422StmtResult Parser::ParseBreakStatement() {
2423 SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
2424 return Actions.ActOnBreakStmt(BreakLoc, CurScope: getCurScope());
2425}
2426
2427/// ParseReturnStatement
2428/// jump-statement:
2429/// 'return' expression[opt] ';'
2430/// 'return' braced-init-list ';'
2431/// 'co_return' expression[opt] ';'
2432/// 'co_return' braced-init-list ';'
2433StmtResult Parser::ParseReturnStatement() {
2434 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2435 "Not a return stmt!");
2436 bool IsCoreturn = Tok.is(K: tok::kw_co_return);
2437 SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
2438
2439 ExprResult R;
2440 if (Tok.isNot(K: tok::semi)) {
2441 if (!IsCoreturn)
2442 PreferredType.enterReturn(S&: Actions, Tok: Tok.getLocation());
2443 // FIXME: Code completion for co_return.
2444 if (Tok.is(K: tok::code_completion) && !IsCoreturn) {
2445 cutOffParsing();
2446 Actions.CodeCompletion().CodeCompleteExpression(
2447 S: getCurScope(), PreferredType: PreferredType.get(Tok: Tok.getLocation()));
2448 return StmtError();
2449 }
2450
2451 if (Tok.is(K: tok::l_brace) && getLangOpts().CPlusPlus) {
2452 R = ParseInitializer();
2453 if (R.isUsable())
2454 Diag(Loc: R.get()->getBeginLoc(),
2455 DiagID: getLangOpts().CPlusPlus11
2456 ? diag::warn_cxx98_compat_generalized_initializer_lists
2457 : diag::ext_generalized_initializer_lists)
2458 << R.get()->getSourceRange();
2459 } else
2460 R = ParseExpression();
2461 if (R.isInvalid()) {
2462 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
2463 return StmtError();
2464 }
2465 }
2466 if (IsCoreturn)
2467 return Actions.ActOnCoreturnStmt(S: getCurScope(), KwLoc: ReturnLoc, E: R.get());
2468 return Actions.ActOnReturnStmt(ReturnLoc, RetValExp: R.get(), CurScope: getCurScope());
2469}
2470
2471StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2472 ParsedStmtContext StmtCtx,
2473 SourceLocation *TrailingElseLoc,
2474 ParsedAttributes &Attrs) {
2475 // Create temporary attribute list.
2476 ParsedAttributes TempAttrs(AttrFactory);
2477
2478 SourceLocation StartLoc = Tok.getLocation();
2479
2480 // Get loop hints and consume annotated token.
2481 while (Tok.is(K: tok::annot_pragma_loop_hint)) {
2482 LoopHint Hint;
2483 if (!HandlePragmaLoopHint(Hint))
2484 continue;
2485
2486 ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.StateLoc,
2487 ArgsUnion(Hint.ValueExpr)};
2488 TempAttrs.addNew(attrName: Hint.PragmaNameLoc->Ident, attrRange: Hint.Range, scopeName: nullptr,
2489 scopeLoc: Hint.PragmaNameLoc->Loc, args: ArgHints, numArgs: 4,
2490 form: ParsedAttr::Form::Pragma());
2491 }
2492
2493 // Get the next statement.
2494 MaybeParseCXX11Attributes(Attrs);
2495
2496 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2497 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2498 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs&: Attrs, GNUAttrs&: EmptyDeclSpecAttrs);
2499
2500 Attrs.takeAllFrom(Other&: TempAttrs);
2501
2502 // Start of attribute range may already be set for some invalid input.
2503 // See PR46336.
2504 if (Attrs.Range.getBegin().isInvalid())
2505 Attrs.Range.setBegin(StartLoc);
2506
2507 return S;
2508}
2509
2510Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
2511 assert(Tok.is(tok::l_brace));
2512 SourceLocation LBraceLoc = Tok.getLocation();
2513
2514 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2515 "parsing function body");
2516
2517 // Save and reset current vtordisp stack if we have entered a C++ method body.
2518 bool IsCXXMethod =
2519 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Val: Decl);
2520 Sema::PragmaStackSentinelRAII
2521 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2522
2523 // Do not enter a scope for the brace, as the arguments are in the same scope
2524 // (the function body) as the body itself. Instead, just read the statement
2525 // list and put it into a CompoundStmt for safe keeping.
2526 StmtResult FnBody(ParseCompoundStatementBody());
2527
2528 // If the function body could not be parsed, make a bogus compoundstmt.
2529 if (FnBody.isInvalid()) {
2530 Sema::CompoundScopeRAII CompoundScope(Actions);
2531 FnBody =
2532 Actions.ActOnCompoundStmt(L: LBraceLoc, R: LBraceLoc, Elts: std::nullopt, isStmtExpr: false);
2533 }
2534
2535 BodyScope.Exit();
2536 return Actions.ActOnFinishFunctionBody(Decl, Body: FnBody.get());
2537}
2538
2539/// ParseFunctionTryBlock - Parse a C++ function-try-block.
2540///
2541/// function-try-block:
2542/// 'try' ctor-initializer[opt] compound-statement handler-seq
2543///
2544Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
2545 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2546 SourceLocation TryLoc = ConsumeToken();
2547
2548 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2549 "parsing function try block");
2550
2551 // Constructor initializer list?
2552 if (Tok.is(K: tok::colon))
2553 ParseConstructorInitializer(ConstructorDecl: Decl);
2554 else
2555 Actions.ActOnDefaultCtorInitializers(CDtorDecl: Decl);
2556
2557 // Save and reset current vtordisp stack if we have entered a C++ method body.
2558 bool IsCXXMethod =
2559 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Val: Decl);
2560 Sema::PragmaStackSentinelRAII
2561 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2562
2563 SourceLocation LBraceLoc = Tok.getLocation();
2564 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));
2565 // If we failed to parse the try-catch, we just give the function an empty
2566 // compound statement as the body.
2567 if (FnBody.isInvalid()) {
2568 Sema::CompoundScopeRAII CompoundScope(Actions);
2569 FnBody =
2570 Actions.ActOnCompoundStmt(L: LBraceLoc, R: LBraceLoc, Elts: std::nullopt, isStmtExpr: false);
2571 }
2572
2573 BodyScope.Exit();
2574 return Actions.ActOnFinishFunctionBody(Decl, Body: FnBody.get());
2575}
2576
2577bool Parser::trySkippingFunctionBody() {
2578 assert(SkipFunctionBodies &&
2579 "Should only be called when SkipFunctionBodies is enabled");
2580 if (!PP.isCodeCompletionEnabled()) {
2581 SkipFunctionBody();
2582 return true;
2583 }
2584
2585 // We're in code-completion mode. Skip parsing for all function bodies unless
2586 // the body contains the code-completion point.
2587 TentativeParsingAction PA(*this);
2588 bool IsTryCatch = Tok.is(K: tok::kw_try);
2589 CachedTokens Toks;
2590 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2591 if (llvm::any_of(Range&: Toks, P: [](const Token &Tok) {
2592 return Tok.is(K: tok::code_completion);
2593 })) {
2594 PA.Revert();
2595 return false;
2596 }
2597 if (ErrorInPrologue) {
2598 PA.Commit();
2599 SkipMalformedDecl();
2600 return true;
2601 }
2602 if (!SkipUntil(T: tok::r_brace, Flags: StopAtCodeCompletion)) {
2603 PA.Revert();
2604 return false;
2605 }
2606 while (IsTryCatch && Tok.is(K: tok::kw_catch)) {
2607 if (!SkipUntil(T: tok::l_brace, Flags: StopAtCodeCompletion) ||
2608 !SkipUntil(T: tok::r_brace, Flags: StopAtCodeCompletion)) {
2609 PA.Revert();
2610 return false;
2611 }
2612 }
2613 PA.Commit();
2614 return true;
2615}
2616
2617/// ParseCXXTryBlock - Parse a C++ try-block.
2618///
2619/// try-block:
2620/// 'try' compound-statement handler-seq
2621///
2622StmtResult Parser::ParseCXXTryBlock() {
2623 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2624
2625 SourceLocation TryLoc = ConsumeToken();
2626 return ParseCXXTryBlockCommon(TryLoc);
2627}
2628
2629/// ParseCXXTryBlockCommon - Parse the common part of try-block and
2630/// function-try-block.
2631///
2632/// try-block:
2633/// 'try' compound-statement handler-seq
2634///
2635/// function-try-block:
2636/// 'try' ctor-initializer[opt] compound-statement handler-seq
2637///
2638/// handler-seq:
2639/// handler handler-seq[opt]
2640///
2641/// [Borland] try-block:
2642/// 'try' compound-statement seh-except-block
2643/// 'try' compound-statement seh-finally-block
2644///
2645StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
2646 if (Tok.isNot(K: tok::l_brace))
2647 return StmtError(Diag(Tok, DiagID: diag::err_expected) << tok::l_brace);
2648
2649 StmtResult TryBlock(ParseCompoundStatement(
2650 /*isStmtExpr=*/false, ScopeFlags: Scope::DeclScope | Scope::TryScope |
2651 Scope::CompoundStmtScope |
2652 (FnTry ? Scope::FnTryCatchScope : 0)));
2653 if (TryBlock.isInvalid())
2654 return TryBlock;
2655
2656 // Borland allows SEH-handlers with 'try'
2657
2658 if ((Tok.is(K: tok::identifier) &&
2659 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2660 Tok.is(K: tok::kw___finally)) {
2661 // TODO: Factor into common return ParseSEHHandlerCommon(...)
2662 StmtResult Handler;
2663 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2664 SourceLocation Loc = ConsumeToken();
2665 Handler = ParseSEHExceptBlock(ExceptLoc: Loc);
2666 }
2667 else {
2668 SourceLocation Loc = ConsumeToken();
2669 Handler = ParseSEHFinallyBlock(FinallyLoc: Loc);
2670 }
2671 if(Handler.isInvalid())
2672 return Handler;
2673
2674 return Actions.ActOnSEHTryBlock(IsCXXTry: true /* IsCXXTry */,
2675 TryLoc,
2676 TryBlock: TryBlock.get(),
2677 Handler: Handler.get());
2678 }
2679 else {
2680 StmtVector Handlers;
2681
2682 // C++11 attributes can't appear here, despite this context seeming
2683 // statement-like.
2684 DiagnoseAndSkipCXX11Attributes();
2685
2686 if (Tok.isNot(K: tok::kw_catch))
2687 return StmtError(Diag(Tok, DiagID: diag::err_expected_catch));
2688 while (Tok.is(K: tok::kw_catch)) {
2689 StmtResult Handler(ParseCXXCatchBlock(FnCatch: FnTry));
2690 if (!Handler.isInvalid())
2691 Handlers.push_back(Elt: Handler.get());
2692 }
2693 // Don't bother creating the full statement if we don't have any usable
2694 // handlers.
2695 if (Handlers.empty())
2696 return StmtError();
2697
2698 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock: TryBlock.get(), Handlers);
2699 }
2700}
2701
2702/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
2703///
2704/// handler:
2705/// 'catch' '(' exception-declaration ')' compound-statement
2706///
2707/// exception-declaration:
2708/// attribute-specifier-seq[opt] type-specifier-seq declarator
2709/// attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
2710/// '...'
2711///
2712StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
2713 assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
2714
2715 SourceLocation CatchLoc = ConsumeToken();
2716
2717 BalancedDelimiterTracker T(*this, tok::l_paren);
2718 if (T.expectAndConsume())
2719 return StmtError();
2720
2721 // C++ 3.3.2p3:
2722 // The name in a catch exception-declaration is local to the handler and
2723 // shall not be redeclared in the outermost block of the handler.
2724 ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
2725 Scope::CatchScope |
2726 (FnCatch ? Scope::FnTryCatchScope : 0));
2727
2728 // exception-declaration is equivalent to '...' or a parameter-declaration
2729 // without default arguments.
2730 Decl *ExceptionDecl = nullptr;
2731 if (Tok.isNot(K: tok::ellipsis)) {
2732 ParsedAttributes Attributes(AttrFactory);
2733 MaybeParseCXX11Attributes(Attrs&: Attributes);
2734
2735 DeclSpec DS(AttrFactory);
2736
2737 if (ParseCXXTypeSpecifierSeq(DS))
2738 return StmtError();
2739
2740 Declarator ExDecl(DS, Attributes, DeclaratorContext::CXXCatch);
2741 ParseDeclarator(D&: ExDecl);
2742 ExceptionDecl = Actions.ActOnExceptionDeclarator(S: getCurScope(), D&: ExDecl);
2743 } else
2744 ConsumeToken();
2745
2746 T.consumeClose();
2747 if (T.getCloseLocation().isInvalid())
2748 return StmtError();
2749
2750 if (Tok.isNot(K: tok::l_brace))
2751 return StmtError(Diag(Tok, DiagID: diag::err_expected) << tok::l_brace);
2752
2753 // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
2754 StmtResult Block(ParseCompoundStatement());
2755 if (Block.isInvalid())
2756 return Block;
2757
2758 return Actions.ActOnCXXCatchBlock(CatchLoc, ExDecl: ExceptionDecl, HandlerBlock: Block.get());
2759}
2760
2761void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2762 IfExistsCondition Result;
2763 if (ParseMicrosoftIfExistsCondition(Result))
2764 return;
2765
2766 // Handle dependent statements by parsing the braces as a compound statement.
2767 // This is not the same behavior as Visual C++, which don't treat this as a
2768 // compound statement, but for Clang's type checking we can't have anything
2769 // inside these braces escaping to the surrounding code.
2770 if (Result.Behavior == IEB_Dependent) {
2771 if (!Tok.is(K: tok::l_brace)) {
2772 Diag(Tok, DiagID: diag::err_expected) << tok::l_brace;
2773 return;
2774 }
2775
2776 StmtResult Compound = ParseCompoundStatement();
2777 if (Compound.isInvalid())
2778 return;
2779
2780 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(KeywordLoc: Result.KeywordLoc,
2781 IsIfExists: Result.IsIfExists,
2782 SS&: Result.SS,
2783 Name&: Result.Name,
2784 Nested: Compound.get());
2785 if (DepResult.isUsable())
2786 Stmts.push_back(Elt: DepResult.get());
2787 return;
2788 }
2789
2790 BalancedDelimiterTracker Braces(*this, tok::l_brace);
2791 if (Braces.consumeOpen()) {
2792 Diag(Tok, DiagID: diag::err_expected) << tok::l_brace;
2793 return;
2794 }
2795
2796 switch (Result.Behavior) {
2797 case IEB_Parse:
2798 // Parse the statements below.
2799 break;
2800
2801 case IEB_Dependent:
2802 llvm_unreachable("Dependent case handled above");
2803
2804 case IEB_Skip:
2805 Braces.skipToEnd();
2806 return;
2807 }
2808
2809 // Condition is true, parse the statements.
2810 while (Tok.isNot(K: tok::r_brace)) {
2811 StmtResult R =
2812 ParseStatementOrDeclaration(Stmts, StmtCtx: ParsedStmtContext::Compound);
2813 if (R.isUsable())
2814 Stmts.push_back(Elt: R.get());
2815 }
2816 Braces.consumeClose();
2817}
2818