Improve parsing and instantiation of destructor names, so that we can
now cope with the destruction of types named as dependent templates,
e.g.,
y->template Y<T>::~Y()
Nominally, we implement C++0x [basic.lookup.qual]p6. However, we don't
follow the letter of the standard here because that would fail to
parse
template<typename T, typename U>
X0<T, U>::~X0() { }
properly. The problem is captured in core issue 339, which gives some
(but not enough!) guidance. I expect to revisit this code when the
resolution of 339 is clear, and/or we start capturing better source
information for DeclarationNames.
Fixes PR6152.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96367 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 51ee6a4..225ce25 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -464,8 +464,7 @@
/// simple-template-id
///
Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
- const CXXScopeSpec *SS,
- bool DestrExpected) {
+ const CXXScopeSpec *SS) {
// Check whether we have a template-id that names a type.
if (Tok.is(tok::annot_template_id)) {
TemplateIdAnnotation *TemplateId
@@ -536,8 +535,7 @@
// We have an identifier; check whether it is actually a type.
TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true);
if (!Type) {
- Diag(IdLoc, DestrExpected ? diag::err_destructor_class_name
- : diag::err_expected_class_name);
+ Diag(IdLoc, diag::err_expected_class_name);
return true;
}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 0dbe1ea..932d6eb 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -846,13 +846,8 @@
EnteringContext, Template);
if (TNK == TNK_Non_template && Id.DestructorName == 0) {
- // The identifier following the destructor did not refer to a template
- // or to a type. Complain.
- if (ObjectType)
- Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
- << Name;
- else
- Diag(NameLoc, diag::err_destructor_class_name);
+ Diag(NameLoc, diag::err_destructor_template_id)
+ << Name << SS.getRange();
return true;
}
}
@@ -1258,7 +1253,7 @@
// Parse the class-name.
if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_destructor_class_name);
+ Diag(Tok, diag::err_destructor_tilde_identifier);
return true;
}
@@ -1273,17 +1268,13 @@
}
// Note that this is a destructor name.
- Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
- CurScope, &SS, false, ObjectType);
- if (!Ty) {
- if (ObjectType)
- Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
- << ClassName;
- else
- Diag(ClassNameLoc, diag::err_destructor_class_name);
+ Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName,
+ ClassNameLoc, CurScope,
+ SS, ObjectType,
+ EnteringContext);
+ if (!Ty)
return true;
- }
-
+
Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
return false;
}