aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp82
1 files changed, 50 insertions, 32 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 7ce9a9c..8d7d37c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6650,48 +6650,66 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
(Tok.is(tok::identifier) &&
(NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) ||
Tok.is(tok::annot_cxxscope))) {
+ TentativeParsingAction TPA(*this, /*Unannotated=*/true);
bool EnteringContext = D.getContext() == DeclaratorContext::File ||
D.getContext() == DeclaratorContext::Member;
CXXScopeSpec SS;
SS.setTemplateParamLists(D.getTemplateParameterLists());
- ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
- /*ObjectHasErrors=*/false, EnteringContext);
- if (SS.isNotEmpty()) {
- if (Tok.isNot(tok::star)) {
- // The scope spec really belongs to the direct-declarator.
- if (D.mayHaveIdentifier())
- D.getCXXScopeSpec() = SS;
- else
- AnnotateScopeToken(SS, true);
+ if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
+ /*ObjectHasErrors=*/false,
+ /*EnteringContext=*/false,
+ /*MayBePseudoDestructor=*/nullptr,
+ /*IsTypename=*/false, /*LastII=*/nullptr,
+ /*OnlyNamespace=*/false,
+ /*InUsingDeclaration=*/false,
+ /*Disambiguation=*/EnteringContext) ||
+
+ SS.isEmpty() || SS.isInvalid() || !EnteringContext ||
+ Tok.is(tok::star)) {
+ TPA.Commit();
+ if (SS.isNotEmpty() && Tok.is(tok::star)) {
+ if (SS.isValid()) {
+ checkCompoundToken(SS.getEndLoc(), tok::coloncolon,
+ CompoundToken::MemberPtr);
+ }
- if (DirectDeclParser)
- (this->*DirectDeclParser)(D);
+ SourceLocation StarLoc = ConsumeToken();
+ D.SetRangeEnd(StarLoc);
+ DeclSpec DS(AttrFactory);
+ ParseTypeQualifierListOpt(DS);
+ D.ExtendWithDeclSpec(DS);
+
+ // Recurse to parse whatever is left.
+ Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] {
+ ParseDeclaratorInternal(D, DirectDeclParser);
+ });
+
+ // Sema will have to catch (syntactically invalid) pointers into global
+ // scope. It has to catch pointers into namespace scope anyway.
+ D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
+ SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()),
+ std::move(DS.getAttributes()),
+ /*EndLoc=*/SourceLocation());
return;
}
+ } else {
+ TPA.Revert();
+ SS.clear();
+ ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
+ /*ObjectHasErrors=*/false,
+ /*EnteringContext=*/true);
+ }
- if (SS.isValid()) {
- checkCompoundToken(SS.getEndLoc(), tok::coloncolon,
- CompoundToken::MemberPtr);
- }
+ if (SS.isNotEmpty()) {
+ // The scope spec really belongs to the direct-declarator.
+ if (D.mayHaveIdentifier())
+ D.getCXXScopeSpec() = SS;
+ else
+ AnnotateScopeToken(SS, true);
- SourceLocation StarLoc = ConsumeToken();
- D.SetRangeEnd(StarLoc);
- DeclSpec DS(AttrFactory);
- ParseTypeQualifierListOpt(DS);
- D.ExtendWithDeclSpec(DS);
-
- // Recurse to parse whatever is left.
- Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] {
- ParseDeclaratorInternal(D, DirectDeclParser);
- });
-
- // Sema will have to catch (syntactically invalid) pointers into global
- // scope. It has to catch pointers into namespace scope anyway.
- D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
- SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()),
- std::move(DS.getAttributes()),
- /* Don't replace range end. */ SourceLocation());
+ if (DirectDeclParser)
+ (this->*DirectDeclParser)(D);
return;
}
}