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.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9bda4ec..a149159 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5835,8 +5835,7 @@ bool Parser::isDeclarationSpecifier(
bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
DeclSpec::FriendSpecified IsFriend,
const ParsedTemplateInfo *TemplateInfo) {
- TentativeParsingAction TPA(*this);
-
+ RevertingTentativeParsingAction TPA(*this);
// Parse the C++ scope specifier.
CXXScopeSpec SS;
if (TemplateInfo && TemplateInfo->TemplateParams)
@@ -5845,7 +5844,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
/*ObjectHasErrors=*/false,
/*EnteringContext=*/true)) {
- TPA.Revert();
return false;
}
@@ -5857,7 +5855,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
} else if (Tok.is(tok::annot_template_id)) {
ConsumeAnnotationToken();
} else {
- TPA.Revert();
return false;
}
@@ -5867,7 +5864,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
// Current class name must be followed by a left parenthesis.
if (Tok.isNot(tok::l_paren)) {
- TPA.Revert();
return false;
}
ConsumeParen();
@@ -5876,7 +5872,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
// that we have a constructor.
if (Tok.is(tok::r_paren) ||
(Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
- TPA.Revert();
return true;
}
@@ -5885,7 +5880,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
if (getLangOpts().CPlusPlus11 &&
isCXX11AttributeSpecifier(/*Disambiguate*/ false,
/*OuterMightBeMessageSend*/ true)) {
- TPA.Revert();
return true;
}
@@ -5906,9 +5900,17 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
// If we parsed a scope specifier as well as friend,
// we might be parsing a friend constructor.
bool IsConstructor = false;
- if (isDeclarationSpecifier(IsFriend && !SS.isSet()
- ? ImplicitTypenameContext::No
- : ImplicitTypenameContext::Yes))
+ ImplicitTypenameContext ITC = IsFriend && !SS.isSet()
+ ? ImplicitTypenameContext::No
+ : ImplicitTypenameContext::Yes;
+ // Constructors cannot have this parameters, but we support that scenario here
+ // to improve diagnostic.
+ if (Tok.is(tok::kw_this)) {
+ ConsumeToken();
+ return isDeclarationSpecifier(ITC);
+ }
+
+ if (isDeclarationSpecifier(ITC))
IsConstructor = true;
else if (Tok.is(tok::identifier) ||
(Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
@@ -5977,8 +5979,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
break;
}
}
-
- TPA.Revert();
return IsConstructor;
}
@@ -7356,6 +7356,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
/// '=' assignment-expression
/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
/// [C++11] attribute-specifier-seq parameter-declaration
+/// [C++2b] attribute-specifier-seq 'this' parameter-declaration
///
void Parser::ParseParameterDeclarationClause(
DeclaratorContext DeclaratorCtx, ParsedAttributes &FirstArgAttrs,
@@ -7420,9 +7421,16 @@ void Parser::ParseParameterDeclarationClause(
SourceLocation DSStart = Tok.getLocation();
+ // Parse a C++23 Explicit Object Parameter
+ // We do that in all language modes to produce a better diagnostic.
+ SourceLocation ThisLoc;
+ if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this))
+ ThisLoc = ConsumeToken();
+
ParseDeclarationSpecifiers(DS, /*TemplateInfo=*/ParsedTemplateInfo(),
AS_none, DeclSpecContext::DSC_normal,
/*LateAttrs=*/nullptr, AllowImplicitTypename);
+
DS.takeAttributesFrom(ArgDeclSpecAttrs);
// Parse the declarator. This is "PrototypeContext" or
@@ -7436,6 +7444,9 @@ void Parser::ParseParameterDeclarationClause(
: DeclaratorContext::Prototype);
ParseDeclarator(ParmDeclarator);
+ if (ThisLoc.isValid())
+ ParmDeclarator.SetRangeBegin(ThisLoc);
+
// Parse GNU attributes, if present.
MaybeParseGNUAttributes(ParmDeclarator);
if (getLangOpts().HLSL)
@@ -7505,7 +7516,8 @@ void Parser::ParseParameterDeclarationClause(
}
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
- Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
+ Decl *Param =
+ Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator, ThisLoc);
// Parse the default argument, if any. We parse the default
// arguments in all dialects; the semantic analysis in
// ActOnParamDefaultArgument will reject the default argument in