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