Skip to content

Commit 91b73f2

Browse files
committed
Switch to an RAII object to revert tentative parsing automatically.
llvm-svn: 274165
1 parent 8ea99cd commit 91b73f2

File tree

2 files changed

+23
-27
lines changed

2 files changed

+23
-27
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,16 @@ class Parser : public CodeCompletionHandler {
715715
assert(!isActive && "Forgot to call Commit or Revert!");
716716
}
717717
};
718+
/// A TentativeParsingAction that automatically reverts in its destructor.
719+
/// Useful for disambiguation parses that will always be reverted.
720+
class RevertingTentativeParsingAction
721+
: private Parser::TentativeParsingAction {
722+
public:
723+
RevertingTentativeParsingAction(Parser &P)
724+
: Parser::TentativeParsingAction(P) {}
725+
~RevertingTentativeParsingAction() { Revert(); }
726+
};
727+
718728
class UnannotatedTentativeParsingAction;
719729

720730
/// ObjCDeclContextSwitch - An object used to switch context from

clang/lib/Parse/ParseTentative.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,11 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
125125
// Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
126126
// or an identifier which doesn't resolve as anything. We need tentative
127127
// parsing...
128-
129-
TentativeParsingAction PA(*this);
130-
TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
131-
PA.Revert();
128+
129+
{
130+
RevertingTentativeParsingAction PA(*this);
131+
TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
132+
}
132133

133134
// In case of an error, let the declaration parsing code handle it.
134135
if (TPR == TPResult::Error)
@@ -354,7 +355,7 @@ bool Parser::isCXXConditionDeclaration() {
354355
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
355356
// We need tentative parsing...
356357

357-
TentativeParsingAction PA(*this);
358+
RevertingTentativeParsingAction PA(*this);
358359

359360
// type-specifier-seq
360361
TryConsumeDeclarationSpecifier();
@@ -378,8 +379,6 @@ bool Parser::isCXXConditionDeclaration() {
378379
TPR = TPResult::False;
379380
}
380381

381-
PA.Revert();
382-
383382
assert(TPR == TPResult::True || TPR == TPResult::False);
384383
return TPR == TPResult::True;
385384
}
@@ -423,7 +422,7 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
423422
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
424423
// We need tentative parsing...
425424

426-
TentativeParsingAction PA(*this);
425+
RevertingTentativeParsingAction PA(*this);
427426

428427
// type-specifier-seq
429428
TryConsumeDeclarationSpecifier();
@@ -456,8 +455,6 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
456455
TPR = TPResult::False;
457456
}
458457

459-
PA.Revert();
460-
461458
assert(TPR == TPResult::True || TPR == TPResult::False);
462459
return TPR == TPResult::True;
463460
}
@@ -508,7 +505,7 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
508505
if (!Disambiguate && !getLangOpts().ObjC1)
509506
return CAK_AttributeSpecifier;
510507

511-
TentativeParsingAction PA(*this);
508+
RevertingTentativeParsingAction PA(*this);
512509

513510
// Opening brackets were checked for above.
514511
ConsumeBracket();
@@ -520,8 +517,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
520517
bool IsAttribute = SkipUntil(tok::r_square);
521518
IsAttribute &= Tok.is(tok::r_square);
522519

523-
PA.Revert();
524-
525520
return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
526521
}
527522

@@ -542,8 +537,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
542537
// A lambda cannot end with ']]', and an attribute must.
543538
bool IsAttribute = Tok.is(tok::r_square);
544539

545-
PA.Revert();
546-
547540
if (IsAttribute)
548541
// Case 1: C++11 attribute.
549542
return CAK_AttributeSpecifier;
@@ -564,7 +557,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
564557
while (Tok.isNot(tok::r_square)) {
565558
if (Tok.is(tok::comma)) {
566559
// Case 1: Stray commas can only occur in attributes.
567-
PA.Revert();
568560
return CAK_AttributeSpecifier;
569561
}
570562

@@ -611,8 +603,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
611603
}
612604
}
613605

614-
PA.Revert();
615-
616606
if (IsAttribute)
617607
// Case 1: C++11 statement attribute.
618608
return CAK_AttributeSpecifier;
@@ -1340,6 +1330,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
13401330
*HasMissingTypename = true;
13411331
return TPResult::Ambiguous;
13421332
}
1333+
1334+
// FIXME: Fails to either revert or commit the tentative parse!
13431335
} else {
13441336
// Try to resolve the name. If it doesn't exist, assume it was
13451337
// intended to name a type and keep disambiguating.
@@ -1391,15 +1383,13 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
13911383
// In Objective-C, we might have a protocol-qualified type.
13921384
if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {
13931385
// Tentatively parse the protocol qualifiers.
1394-
TentativeParsingAction PA(*this);
1386+
RevertingTentativeParsingAction PA(*this);
13951387
ConsumeToken(); // The type token
13961388

13971389
TPResult TPR = TryParseProtocolQualifiers();
13981390
bool isFollowedByParen = Tok.is(tok::l_paren);
13991391
bool isFollowedByBrace = Tok.is(tok::l_brace);
14001392

1401-
PA.Revert();
1402-
14031393
if (TPR == TPResult::Error)
14041394
return TPResult::Error;
14051395

@@ -1452,14 +1442,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
14521442
if (NextToken().isNot(tok::l_paren))
14531443
return TPResult::True;
14541444

1455-
TentativeParsingAction PA(*this);
1445+
RevertingTentativeParsingAction PA(*this);
14561446

14571447
TPResult TPR = TryParseTypeofSpecifier();
14581448
bool isFollowedByParen = Tok.is(tok::l_paren);
14591449
bool isFollowedByBrace = Tok.is(tok::l_brace);
14601450

1461-
PA.Revert();
1462-
14631451
if (TPR == TPResult::Error)
14641452
return TPResult::Error;
14651453

@@ -1599,7 +1587,7 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
15991587
// ambiguities mentioned in 6.8, the resolution is to consider any construct
16001588
// that could possibly be a declaration a declaration.
16011589

1602-
TentativeParsingAction PA(*this);
1590+
RevertingTentativeParsingAction PA(*this);
16031591

16041592
ConsumeParen();
16051593
bool InvalidAsDeclaration = false;
@@ -1623,8 +1611,6 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
16231611
}
16241612
}
16251613

1626-
PA.Revert();
1627-
16281614
if (IsAmbiguous && TPR == TPResult::Ambiguous)
16291615
*IsAmbiguous = true;
16301616

0 commit comments

Comments
 (0)