Coverage Report

Created: 2024-01-17 10:31

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