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