@@ -125,10 +125,11 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
125
125
// Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
126
126
// or an identifier which doesn't resolve as anything. We need tentative
127
127
// parsing...
128
-
129
- TentativeParsingAction PA (*this );
130
- TPR = TryParseSimpleDeclaration (AllowForRangeDecl);
131
- PA.Revert ();
128
+
129
+ {
130
+ RevertingTentativeParsingAction PA (*this );
131
+ TPR = TryParseSimpleDeclaration (AllowForRangeDecl);
132
+ }
132
133
133
134
// In case of an error, let the declaration parsing code handle it.
134
135
if (TPR == TPResult::Error)
@@ -354,7 +355,7 @@ bool Parser::isCXXConditionDeclaration() {
354
355
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
355
356
// We need tentative parsing...
356
357
357
- TentativeParsingAction PA (*this );
358
+ RevertingTentativeParsingAction PA (*this );
358
359
359
360
// type-specifier-seq
360
361
TryConsumeDeclarationSpecifier ();
@@ -378,8 +379,6 @@ bool Parser::isCXXConditionDeclaration() {
378
379
TPR = TPResult::False;
379
380
}
380
381
381
- PA.Revert ();
382
-
383
382
assert (TPR == TPResult::True || TPR == TPResult::False);
384
383
return TPR == TPResult::True;
385
384
}
@@ -423,7 +422,7 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
423
422
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
424
423
// We need tentative parsing...
425
424
426
- TentativeParsingAction PA (*this );
425
+ RevertingTentativeParsingAction PA (*this );
427
426
428
427
// type-specifier-seq
429
428
TryConsumeDeclarationSpecifier ();
@@ -456,8 +455,6 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
456
455
TPR = TPResult::False;
457
456
}
458
457
459
- PA.Revert ();
460
-
461
458
assert (TPR == TPResult::True || TPR == TPResult::False);
462
459
return TPR == TPResult::True;
463
460
}
@@ -508,7 +505,7 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
508
505
if (!Disambiguate && !getLangOpts ().ObjC1 )
509
506
return CAK_AttributeSpecifier;
510
507
511
- TentativeParsingAction PA (*this );
508
+ RevertingTentativeParsingAction PA (*this );
512
509
513
510
// Opening brackets were checked for above.
514
511
ConsumeBracket ();
@@ -520,8 +517,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
520
517
bool IsAttribute = SkipUntil (tok::r_square);
521
518
IsAttribute &= Tok.is (tok::r_square);
522
519
523
- PA.Revert ();
524
-
525
520
return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
526
521
}
527
522
@@ -542,8 +537,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
542
537
// A lambda cannot end with ']]', and an attribute must.
543
538
bool IsAttribute = Tok.is (tok::r_square);
544
539
545
- PA.Revert ();
546
-
547
540
if (IsAttribute)
548
541
// Case 1: C++11 attribute.
549
542
return CAK_AttributeSpecifier;
@@ -564,7 +557,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
564
557
while (Tok.isNot (tok::r_square)) {
565
558
if (Tok.is (tok::comma)) {
566
559
// Case 1: Stray commas can only occur in attributes.
567
- PA.Revert ();
568
560
return CAK_AttributeSpecifier;
569
561
}
570
562
@@ -611,8 +603,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
611
603
}
612
604
}
613
605
614
- PA.Revert ();
615
-
616
606
if (IsAttribute)
617
607
// Case 1: C++11 statement attribute.
618
608
return CAK_AttributeSpecifier;
@@ -1340,6 +1330,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1340
1330
*HasMissingTypename = true ;
1341
1331
return TPResult::Ambiguous;
1342
1332
}
1333
+
1334
+ // FIXME: Fails to either revert or commit the tentative parse!
1343
1335
} else {
1344
1336
// Try to resolve the name. If it doesn't exist, assume it was
1345
1337
// intended to name a type and keep disambiguating.
@@ -1391,15 +1383,13 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1391
1383
// In Objective-C, we might have a protocol-qualified type.
1392
1384
if (getLangOpts ().ObjC1 && NextToken ().is (tok::less)) {
1393
1385
// Tentatively parse the protocol qualifiers.
1394
- TentativeParsingAction PA (*this );
1386
+ RevertingTentativeParsingAction PA (*this );
1395
1387
ConsumeToken (); // The type token
1396
1388
1397
1389
TPResult TPR = TryParseProtocolQualifiers ();
1398
1390
bool isFollowedByParen = Tok.is (tok::l_paren);
1399
1391
bool isFollowedByBrace = Tok.is (tok::l_brace);
1400
1392
1401
- PA.Revert ();
1402
-
1403
1393
if (TPR == TPResult::Error)
1404
1394
return TPResult::Error;
1405
1395
@@ -1452,14 +1442,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1452
1442
if (NextToken ().isNot (tok::l_paren))
1453
1443
return TPResult::True;
1454
1444
1455
- TentativeParsingAction PA (*this );
1445
+ RevertingTentativeParsingAction PA (*this );
1456
1446
1457
1447
TPResult TPR = TryParseTypeofSpecifier ();
1458
1448
bool isFollowedByParen = Tok.is (tok::l_paren);
1459
1449
bool isFollowedByBrace = Tok.is (tok::l_brace);
1460
1450
1461
- PA.Revert ();
1462
-
1463
1451
if (TPR == TPResult::Error)
1464
1452
return TPResult::Error;
1465
1453
@@ -1599,7 +1587,7 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
1599
1587
// ambiguities mentioned in 6.8, the resolution is to consider any construct
1600
1588
// that could possibly be a declaration a declaration.
1601
1589
1602
- TentativeParsingAction PA (*this );
1590
+ RevertingTentativeParsingAction PA (*this );
1603
1591
1604
1592
ConsumeParen ();
1605
1593
bool InvalidAsDeclaration = false ;
@@ -1623,8 +1611,6 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
1623
1611
}
1624
1612
}
1625
1613
1626
- PA.Revert ();
1627
-
1628
1614
if (IsAmbiguous && TPR == TPResult::Ambiguous)
1629
1615
*IsAmbiguous = true ;
1630
1616
0 commit comments