@@ -417,6 +417,8 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
417
417
// / if-statement: [C99 6.8.4.1]
418
418
// / 'if' '(' expression ')' statement
419
419
// / 'if' '(' expression ')' statement 'else' statement
420
+ // / [C++] 'if' '(' condition ')' statement
421
+ // / [C++] 'if' '(' condition ')' statement 'else' statement
420
422
// /
421
423
Parser::StmtResult Parser::ParseIfStatement () {
422
424
assert (Tok.is (tok::kw_if) && " Not an if stmt!" );
@@ -427,27 +429,37 @@ Parser::StmtResult Parser::ParseIfStatement() {
427
429
SkipUntil (tok::semi);
428
430
return true ;
429
431
}
430
-
432
+
433
+ bool C99orCXX = getLang ().C99 || getLang ().CPlusPlus ;
434
+
431
435
// C99 6.8.4p3 - In C99, the if statement is a block. This is not
432
436
// the case for C90.
433
- if (getLang (). C99 )
434
- EnterScope (Scope::DeclScope);
437
+ if (C99orCXX )
438
+ EnterScope (Scope::DeclScope | Scope::ControlScope );
435
439
436
440
// Parse the condition.
437
- ExprResult CondExp = ParseSimpleParenExpression ();
441
+ ExprResult CondExp;
442
+ if (getLang ().CPlusPlus ) {
443
+ SourceLocation LParenLoc = ConsumeParen ();
444
+ CondExp = ParseCXXCondition ();
445
+ MatchRHSPunctuation (tok::r_paren, LParenLoc);
446
+ } else {
447
+ CondExp = ParseSimpleParenExpression ();
448
+ }
449
+
438
450
if (CondExp.isInvalid ) {
439
451
SkipUntil (tok::semi);
440
- if (getLang (). C99 )
452
+ if (C99orCXX )
441
453
ExitScope ();
442
454
return true ;
443
455
}
444
456
445
457
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
446
458
// there is no compound stmt. C90 does not have this clause. We only do this
447
459
// if the body isn't a compound statement to avoid push/pop in common cases.
448
- bool NeedsInnerScope = getLang (). C99 && Tok.isNot (tok::l_brace);
460
+ bool NeedsInnerScope = C99orCXX && Tok.isNot (tok::l_brace);
449
461
if (NeedsInnerScope) EnterScope (Scope::DeclScope);
450
-
462
+
451
463
// Read the 'then' stmt.
452
464
SourceLocation ThenStmtLoc = Tok.getLocation ();
453
465
StmtResult ThenStmt = ParseStatement ();
@@ -467,7 +479,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
467
479
// there is no compound stmt. C90 does not have this clause. We only do
468
480
// this if the body isn't a compound statement to avoid push/pop in common
469
481
// cases.
470
- NeedsInnerScope = getLang (). C99 && Tok.isNot (tok::l_brace);
482
+ NeedsInnerScope = C99orCXX && Tok.isNot (tok::l_brace);
471
483
if (NeedsInnerScope) EnterScope (Scope::DeclScope);
472
484
473
485
ElseStmtLoc = Tok.getLocation ();
@@ -477,7 +489,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
477
489
if (NeedsInnerScope) ExitScope ();
478
490
}
479
491
480
- if (getLang (). C99 )
492
+ if (C99orCXX )
481
493
ExitScope ();
482
494
483
495
// If the then or else stmt is invalid and the other is valid (and present),
@@ -505,6 +517,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
505
517
// / ParseSwitchStatement
506
518
// / switch-statement:
507
519
// / 'switch' '(' expression ')' statement
520
+ // / [C++] 'switch' '(' condition ')' statement
508
521
Parser::StmtResult Parser::ParseSwitchStatement () {
509
522
assert (Tok.is (tok::kw_switch) && " Not a switch stmt!" );
510
523
SourceLocation SwitchLoc = ConsumeToken (); // eat the 'switch'.
@@ -515,15 +528,24 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
515
528
return true ;
516
529
}
517
530
531
+ bool C99orCXX = getLang ().C99 || getLang ().CPlusPlus ;
532
+
518
533
// C99 6.8.4p3 - In C99, the switch statement is a block. This is
519
534
// not the case for C90. Start the switch scope.
520
- if (getLang (). C99 )
521
- EnterScope (Scope::BreakScope| Scope::DeclScope);
535
+ if (C99orCXX )
536
+ EnterScope (Scope::BreakScope | Scope::DeclScope | Scope::ControlScope );
522
537
else
523
538
EnterScope (Scope::BreakScope);
524
539
525
540
// Parse the condition.
526
- ExprResult Cond = ParseSimpleParenExpression ();
541
+ ExprResult Cond;
542
+ if (getLang ().CPlusPlus ) {
543
+ SourceLocation LParenLoc = ConsumeParen ();
544
+ Cond = ParseCXXCondition ();
545
+ MatchRHSPunctuation (tok::r_paren, LParenLoc);
546
+ } else {
547
+ Cond = ParseSimpleParenExpression ();
548
+ }
527
549
528
550
if (Cond.isInvalid ) {
529
551
ExitScope ();
@@ -535,7 +557,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
535
557
// C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
536
558
// there is no compound stmt. C90 does not have this clause. We only do this
537
559
// if the body isn't a compound statement to avoid push/pop in common cases.
538
- bool NeedsInnerScope = getLang (). C99 && Tok.isNot (tok::l_brace);
560
+ bool NeedsInnerScope = C99orCXX && Tok.isNot (tok::l_brace);
539
561
if (NeedsInnerScope) EnterScope (Scope::DeclScope);
540
562
541
563
// Read the body statement.
@@ -557,6 +579,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
557
579
// / ParseWhileStatement
558
580
// / while-statement: [C99 6.8.5.1]
559
581
// / 'while' '(' expression ')' statement
582
+ // / [C++] 'while' '(' condition ')' statement
560
583
Parser::StmtResult Parser::ParseWhileStatement () {
561
584
assert (Tok.is (tok::kw_while) && " Not a while stmt!" );
562
585
SourceLocation WhileLoc = Tok.getLocation ();
@@ -568,20 +591,30 @@ Parser::StmtResult Parser::ParseWhileStatement() {
568
591
return true ;
569
592
}
570
593
594
+ bool C99orCXX = getLang ().C99 || getLang ().CPlusPlus ;
595
+
571
596
// C99 6.8.5p5 - In C99, the while statement is a block. This is not
572
597
// the case for C90. Start the loop scope.
573
- if (getLang ().C99 )
574
- EnterScope (Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
598
+ if (C99orCXX)
599
+ EnterScope (Scope::BreakScope | Scope::ContinueScope |
600
+ Scope::DeclScope | Scope::ControlScope);
575
601
else
576
602
EnterScope (Scope::BreakScope | Scope::ContinueScope);
577
603
578
604
// Parse the condition.
579
- ExprResult Cond = ParseSimpleParenExpression ();
605
+ ExprResult Cond;
606
+ if (getLang ().CPlusPlus ) {
607
+ SourceLocation LParenLoc = ConsumeParen ();
608
+ Cond = ParseCXXCondition ();
609
+ MatchRHSPunctuation (tok::r_paren, LParenLoc);
610
+ } else {
611
+ Cond = ParseSimpleParenExpression ();
612
+ }
580
613
581
614
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
582
615
// there is no compound stmt. C90 does not have this clause. We only do this
583
616
// if the body isn't a compound statement to avoid push/pop in common cases.
584
- bool NeedsInnerScope = getLang (). C99 && Tok.isNot (tok::l_brace);
617
+ bool NeedsInnerScope = C99orCXX && Tok.isNot (tok::l_brace);
585
618
if (NeedsInnerScope) EnterScope (Scope::DeclScope);
586
619
587
620
// Read the body statement.
@@ -654,8 +687,15 @@ Parser::StmtResult Parser::ParseDoStatement() {
654
687
// / for-statement: [C99 6.8.5.3]
655
688
// / 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
656
689
// / 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
690
+ // / [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
691
+ // / [C++] statement
657
692
// / [OBJC2] 'for' '(' declaration 'in' expr ')' statement
658
693
// / [OBJC2] 'for' '(' expr 'in' expr ')' statement
694
+ // /
695
+ // / [C++] for-init-statement:
696
+ // / [C++] expression-statement
697
+ // / [C++] simple-declaration
698
+ // /
659
699
Parser::StmtResult Parser::ParseForStatement () {
660
700
assert (Tok.is (tok::kw_for) && " Not a for stmt!" );
661
701
SourceLocation ForLoc = ConsumeToken (); // eat the 'for'.
@@ -666,10 +706,13 @@ Parser::StmtResult Parser::ParseForStatement() {
666
706
return true ;
667
707
}
668
708
709
+ bool C99orCXX = getLang ().C99 || getLang ().CPlusPlus ;
710
+
669
711
// C99 6.8.5p5 - In C99, the for statement is a block. This is not
670
712
// the case for C90. Start the loop scope.
671
- if (getLang ().C99 )
672
- EnterScope (Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
713
+ if (C99orCXX)
714
+ EnterScope (Scope::BreakScope | Scope::ContinueScope |
715
+ Scope::DeclScope | Scope::ControlScope);
673
716
else
674
717
EnterScope (Scope::BreakScope | Scope::ContinueScope);
675
718
@@ -687,11 +730,11 @@ Parser::StmtResult Parser::ParseForStatement() {
687
730
ConsumeToken ();
688
731
} else if (isDeclarationSpecifier ()) { // for (int X = 4;
689
732
// Parse declaration, which eats the ';'.
690
- if (!getLang (). C99 ) // Use of C99-style for loops in C90 mode?
733
+ if (!C99orCXX ) // Use of C99-style for loops in C90 mode?
691
734
Diag (Tok, diag::ext_c99_variable_decl_in_for_loop);
692
735
693
736
SourceLocation DeclStart = Tok.getLocation ();
694
- DeclTy *aBlockVarDecl = ParseDeclaration (Declarator::ForContext);
737
+ DeclTy *aBlockVarDecl = ParseSimpleDeclaration (Declarator::ForContext);
695
738
// FIXME: Pass in the right location for the end of the declstmt.
696
739
StmtResult stmtResult = Actions.ActOnDeclStmt (aBlockVarDecl, DeclStart,
697
740
DeclStart);
@@ -732,7 +775,8 @@ Parser::StmtResult Parser::ParseForStatement() {
732
775
// no second part.
733
776
Value = ExprResult ();
734
777
} else {
735
- Value = ParseExpression ();
778
+ Value = getLang ().CPlusPlus ? ParseCXXCondition ()
779
+ : ParseExpression ();
736
780
if (!Value.isInvalid )
737
781
SecondPart = Value.Val ;
738
782
}
@@ -764,7 +808,7 @@ Parser::StmtResult Parser::ParseForStatement() {
764
808
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
765
809
// there is no compound stmt. C90 does not have this clause. We only do this
766
810
// if the body isn't a compound statement to avoid push/pop in common cases.
767
- bool NeedsInnerScope = getLang (). C99 && Tok.isNot (tok::l_brace);
811
+ bool NeedsInnerScope = C99orCXX && Tok.isNot (tok::l_brace);
768
812
if (NeedsInnerScope) EnterScope (Scope::DeclScope);
769
813
770
814
// Read the body statement.
0 commit comments