@@ -6650,48 +6650,67 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
66506650 (Tok.is (tok::identifier) &&
66516651 (NextToken ().is (tok::coloncolon) || NextToken ().is (tok::less))) ||
66526652 Tok.is (tok::annot_cxxscope))) {
6653+ TentativeParsingAction TPA (*this , /* Unannotated=*/ true );
66536654 bool EnteringContext = D.getContext () == DeclaratorContext::File ||
66546655 D.getContext () == DeclaratorContext::Member;
6656+
66556657 CXXScopeSpec SS;
66566658 SS.setTemplateParamLists (D.getTemplateParameterLists ());
6657- ParseOptionalCXXScopeSpecifier (SS, /* ObjectType=*/ nullptr ,
6658- /* ObjectHasErrors=*/ false , EnteringContext);
66596659
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+ }
66676677
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 ());
66706695 return ;
66716696 }
6697+ } else {
6698+ TPA.Revert ();
6699+ SS.clear ();
6700+ ParseOptionalCXXScopeSpecifier (SS, /* ObjectType=*/ nullptr ,
6701+ /* ObjectHasErrors=*/ false ,
6702+ /* EnteringContext=*/ true );
6703+ }
66726704
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 );
66776711
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);
66956714 return ;
66966715 }
66976716 }
0 commit comments