forked from OSchip/llvm-project
Fix constructor declarator detection for the case when the name is followed by
an attribute-specifier-seq. (Also fixes the same problem for deduction-guides.) llvm-svn: 294396
This commit is contained in:
parent
f283fdcd50
commit
8f8697f3e1
|
@ -4675,6 +4675,10 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There may be attributes here, appertaining to the constructor name or type
|
||||||
|
// we just stepped past.
|
||||||
|
SkipCXX11Attributes();
|
||||||
|
|
||||||
// Current class name must be followed by a left parenthesis.
|
// Current class name must be followed by a left parenthesis.
|
||||||
if (Tok.isNot(tok::l_paren)) {
|
if (Tok.isNot(tok::l_paren)) {
|
||||||
TPA.Revert();
|
TPA.Revert();
|
||||||
|
@ -4742,18 +4746,24 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) {
|
||||||
|
|
||||||
case tok::r_paren:
|
case tok::r_paren:
|
||||||
// C(X )
|
// C(X )
|
||||||
|
|
||||||
|
// Skip past the right-paren and any following attributes to get to
|
||||||
|
// the function body or trailing-return-type.
|
||||||
|
ConsumeParen();
|
||||||
|
SkipCXX11Attributes();
|
||||||
|
|
||||||
if (DeductionGuide) {
|
if (DeductionGuide) {
|
||||||
// C(X) -> ... is a deduction guide.
|
// C(X) -> ... is a deduction guide.
|
||||||
IsConstructor = NextToken().is(tok::arrow);
|
IsConstructor = Tok.is(tok::arrow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (NextToken().is(tok::colon) || NextToken().is(tok::kw_try)) {
|
if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
|
||||||
// Assume these were meant to be constructors:
|
// Assume these were meant to be constructors:
|
||||||
// C(X) : (the name of a bit-field cannot be parenthesized).
|
// C(X) : (the name of a bit-field cannot be parenthesized).
|
||||||
// C(X) try (this is otherwise ill-formed).
|
// C(X) try (this is otherwise ill-formed).
|
||||||
IsConstructor = true;
|
IsConstructor = true;
|
||||||
}
|
}
|
||||||
if (NextToken().is(tok::semi) || NextToken().is(tok::l_brace)) {
|
if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
|
||||||
// If we have a constructor name within the class definition,
|
// If we have a constructor name within the class definition,
|
||||||
// assume these were meant to be constructors:
|
// assume these were meant to be constructors:
|
||||||
// C(X) {
|
// C(X) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ A(int(&)[5])[3] -> A<int>;
|
||||||
|
|
||||||
// (Pending DR) attributes and parens around the declarator-id are OK.
|
// (Pending DR) attributes and parens around the declarator-id are OK.
|
||||||
[[deprecated]] A(int(&)[6]) [[]] -> A<int> [[]];
|
[[deprecated]] A(int(&)[6]) [[]] -> A<int> [[]];
|
||||||
A [[]] (int(&)[7]) -> A<int>; // FIXME: expected-error 2{{expected}} expected-note {{to match}}
|
A [[]] (int(&)[7]) -> A<int>;
|
||||||
(A)(int(&)[8]) -> A<int>;
|
(A)(int(&)[8]) -> A<int>;
|
||||||
|
|
||||||
// ... but the trailing-return-type is part of the function-declarator as normal
|
// ... but the trailing-return-type is part of the function-declarator as normal
|
||||||
|
|
|
@ -99,11 +99,13 @@ void fn_with_structs() {
|
||||||
}
|
}
|
||||||
[[]];
|
[[]];
|
||||||
struct ctordtor {
|
struct ctordtor {
|
||||||
[[]] ctordtor();
|
[[]] ctordtor [[]] () [[]];
|
||||||
[[]] ~ctordtor();
|
ctordtor (C) [[]];
|
||||||
|
[[]] ~ctordtor [[]] () [[]];
|
||||||
};
|
};
|
||||||
[[]] ctordtor::ctordtor() {}
|
[[]] ctordtor::ctordtor [[]] () [[]] {}
|
||||||
[[]] ctordtor::~ctordtor() {}
|
[[]] ctordtor::ctordtor (C) [[]] try {} catch (...) {}
|
||||||
|
[[]] ctordtor::~ctordtor [[]] () [[]] {}
|
||||||
extern "C++" [[]] int extern_attr;
|
extern "C++" [[]] int extern_attr;
|
||||||
template <typename T> [[]] void template_attr ();
|
template <typename T> [[]] void template_attr ();
|
||||||
[[]] [[]] int [[]] [[]] multi_attr [[]] [[]];
|
[[]] [[]] int [[]] [[]] multi_attr [[]] [[]];
|
||||||
|
|
Loading…
Reference in New Issue