@@ -6650,48 +6650,67 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
6650
6650
(Tok.is (tok::identifier) &&
6651
6651
(NextToken ().is (tok::coloncolon) || NextToken ().is (tok::less))) ||
6652
6652
Tok.is (tok::annot_cxxscope))) {
6653
+ TentativeParsingAction TPA (*this , /* Unannotated=*/ true );
6653
6654
bool EnteringContext = D.getContext () == DeclaratorContext::File ||
6654
6655
D.getContext () == DeclaratorContext::Member;
6656
+
6655
6657
CXXScopeSpec SS;
6656
6658
SS.setTemplateParamLists (D.getTemplateParameterLists ());
6657
- ParseOptionalCXXScopeSpecifier (SS, /* ObjectType=*/ nullptr ,
6658
- /* ObjectHasErrors=*/ false , EnteringContext);
6659
6659
6660
- if (SS.isNotEmpty ()) {
6661
- if (Tok.isNot (tok::star)) {
6662
- // The scope spec really belongs to the direct-declarator.
6663
- if (D.mayHaveIdentifier ())
6664
- D.getCXXScopeSpec () = SS;
6665
- else
6666
- AnnotateScopeToken (SS, true );
6660
+ if (ParseOptionalCXXScopeSpecifier (SS, /* ObjectType=*/ nullptr ,
6661
+ /* ObjectHasErrors=*/ false ,
6662
+ /* EnteringContext=*/ false ,
6663
+ /* MayBePseudoDestructor=*/ nullptr ,
6664
+ /* IsTypename=*/ false , /* LastII=*/ nullptr ,
6665
+ /* OnlyNamespace=*/ false ,
6666
+ /* InUsingDeclaration=*/ false ,
6667
+ /* Disambiguation=*/ EnteringContext) ||
6668
+
6669
+ SS.isEmpty () || SS.isInvalid () || !EnteringContext ||
6670
+ Tok.is (tok::star)) {
6671
+ TPA.Commit ();
6672
+ if (SS.isNotEmpty () && Tok.is (tok::star)) {
6673
+ if (SS.isValid ()) {
6674
+ checkCompoundToken (SS.getEndLoc (), tok::coloncolon,
6675
+ CompoundToken::MemberPtr);
6676
+ }
6667
6677
6668
- if (DirectDeclParser)
6669
- (this ->*DirectDeclParser)(D);
6678
+ SourceLocation StarLoc = ConsumeToken ();
6679
+ D.SetRangeEnd (StarLoc);
6680
+ DeclSpec DS (AttrFactory);
6681
+ ParseTypeQualifierListOpt (DS);
6682
+ D.ExtendWithDeclSpec (DS);
6683
+
6684
+ // Recurse to parse whatever is left.
6685
+ Actions.runWithSufficientStackSpace (D.getBeginLoc (), [&] {
6686
+ ParseDeclaratorInternal (D, DirectDeclParser);
6687
+ });
6688
+
6689
+ // Sema will have to catch (syntactically invalid) pointers into global
6690
+ // scope. It has to catch pointers into namespace scope anyway.
6691
+ D.AddTypeInfo (DeclaratorChunk::getMemberPointer (
6692
+ SS, DS.getTypeQualifiers (), StarLoc, DS.getEndLoc ()),
6693
+ std::move (DS.getAttributes ()),
6694
+ /* EndLoc=*/ SourceLocation ());
6670
6695
return ;
6671
6696
}
6697
+ } else {
6698
+ TPA.Revert ();
6699
+ SS.clear ();
6700
+ ParseOptionalCXXScopeSpecifier (SS, /* ObjectType=*/ nullptr ,
6701
+ /* ObjectHasErrors=*/ false ,
6702
+ /* EnteringContext=*/ true );
6703
+ }
6672
6704
6673
- if (SS.isValid ()) {
6674
- checkCompoundToken (SS.getEndLoc (), tok::coloncolon,
6675
- CompoundToken::MemberPtr);
6676
- }
6705
+ if (SS.isNotEmpty ()) {
6706
+ // The scope spec really belongs to the direct-declarator.
6707
+ if (D.mayHaveIdentifier ())
6708
+ D.getCXXScopeSpec () = SS;
6709
+ else
6710
+ AnnotateScopeToken (SS, true );
6677
6711
6678
- SourceLocation StarLoc = ConsumeToken ();
6679
- D.SetRangeEnd (StarLoc);
6680
- DeclSpec DS (AttrFactory);
6681
- ParseTypeQualifierListOpt (DS);
6682
- D.ExtendWithDeclSpec (DS);
6683
-
6684
- // Recurse to parse whatever is left.
6685
- Actions.runWithSufficientStackSpace (D.getBeginLoc (), [&] {
6686
- ParseDeclaratorInternal (D, DirectDeclParser);
6687
- });
6688
-
6689
- // Sema will have to catch (syntactically invalid) pointers into global
6690
- // scope. It has to catch pointers into namespace scope anyway.
6691
- D.AddTypeInfo (DeclaratorChunk::getMemberPointer (
6692
- SS, DS.getTypeQualifiers (), StarLoc, DS.getEndLoc ()),
6693
- std::move (DS.getAttributes ()),
6694
- /* Don't replace range end. */ SourceLocation ());
6712
+ if (DirectDeclParser)
6713
+ (this ->*DirectDeclParser)(D);
6695
6714
return ;
6696
6715
}
6697
6716
}
0 commit comments