forked from OSchip/llvm-project
Add error, recovery and fixit for "~A::A() {...}".
llvm-svn: 217302
This commit is contained in:
parent
d650b82b22
commit
efa6f736e6
|
@ -492,6 +492,8 @@ def err_constructor_bad_name : Error<
|
|||
"missing return type for function %0; did you mean the constructor name %1?">;
|
||||
def err_destructor_tilde_identifier : Error<
|
||||
"expected a class name after '~' to name a destructor">;
|
||||
def err_destructor_tilde_scope : Error<
|
||||
"'~' in destructor name should be after nested name specifier">;
|
||||
def err_destructor_template_id : Error<
|
||||
"destructor name %0 does not refer to a template">;
|
||||
def err_default_arg_unparsed : Error<
|
||||
|
|
|
@ -2452,10 +2452,29 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
|
|||
return true;
|
||||
}
|
||||
|
||||
// If the user wrote ~T::T, correct it to T::~T.
|
||||
if (!TemplateSpecified && NextToken().is(tok::coloncolon)) {
|
||||
if (SS.isSet()) {
|
||||
AnnotateScopeToken(SS, /*NewAnnotation*/true);
|
||||
SS.clear();
|
||||
}
|
||||
if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, EnteringContext))
|
||||
return true;
|
||||
if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon)) {
|
||||
Diag(TildeLoc, diag::err_destructor_tilde_scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Recover as if the tilde had been written before the identifier.
|
||||
Diag(TildeLoc, diag::err_destructor_tilde_scope)
|
||||
<< FixItHint::CreateRemoval(TildeLoc)
|
||||
<< FixItHint::CreateInsertion(Tok.getLocation(), "~");
|
||||
}
|
||||
|
||||
// Parse the class-name (or template-name in a simple-template-id).
|
||||
IdentifierInfo *ClassName = Tok.getIdentifierInfo();
|
||||
SourceLocation ClassNameLoc = ConsumeToken();
|
||||
|
||||
|
||||
if (TemplateSpecified || Tok.is(tok::less)) {
|
||||
Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc);
|
||||
return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
|
||||
|
@ -2463,7 +2482,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
|
|||
EnteringContext, ObjectType,
|
||||
Result, TemplateSpecified);
|
||||
}
|
||||
|
||||
|
||||
// Note that this is a destructor name.
|
||||
ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName,
|
||||
ClassNameLoc, getCurScope(),
|
||||
|
|
|
@ -308,6 +308,13 @@ namespace dtor_fixit {
|
|||
~bar() { } // expected-error {{expected the class name after '~' to name a destructor}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:9}:"foo"
|
||||
};
|
||||
|
||||
class bar {
|
||||
~bar();
|
||||
};
|
||||
~bar::bar() {} // expected-error {{'~' in destructor name should be after nested name specifier}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:4}:""
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:9-[[@LINE-2]]:9}:"~"
|
||||
}
|
||||
|
||||
namespace PR5066 {
|
||||
|
|
|
@ -139,6 +139,20 @@ namespace CtorErrors {
|
|||
};
|
||||
}
|
||||
|
||||
namespace DtorErrors {
|
||||
struct A { ~A(); } a;
|
||||
~A::A() {} // expected-error {{'~' in destructor name should be after nested name specifier}} expected-note {{previous}}
|
||||
A::~A() {} // expected-error {{redefinition}}
|
||||
|
||||
struct B { ~B(); } *b;
|
||||
DtorErrors::~B::B() {} // expected-error {{'~' in destructor name should be after nested name specifier}}
|
||||
|
||||
void f() {
|
||||
a.~A::A(); // expected-error {{'~' in destructor name should be after nested name specifier}}
|
||||
b->~DtorErrors::~B::B(); // expected-error {{'~' in destructor name should be after nested name specifier}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace BadFriend {
|
||||
struct A {
|
||||
friend int : 3; // expected-error {{friends can only be classes or functions}}
|
||||
|
|
Loading…
Reference in New Issue