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/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index 6837cd4..a0c2c1e 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -40,9 +40,9 @@
~F(); // expected-error {{destructor cannot be redeclared}}
};
-~; // expected-error {{expected the class name after '~' to name a destructor}}
+~; // expected-error {{expected a class name after '~' to name a destructor}}
~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
-~operator+(int, int); // expected-error {{expected the class name after '~' to name a destructor}}
+~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}}
~F(){} // expected-error {{destructor must be a non-static member function}}
struct G {
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
index 666595c..7b17afb 100644
--- a/test/SemaCXX/invalid-member-expr.cpp
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -6,7 +6,7 @@
X x;
x.int; // expected-error{{expected unqualified-id}}
- x.~int(); // expected-error{{expected the class name}}
+ x.~int(); // expected-error{{expected a class name}}
x.operator; // expected-error{{missing type specifier after 'operator'}}
x.operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
@@ -15,7 +15,7 @@
X *x;
x->int; // expected-error{{expected unqualified-id}}
- x->~int(); // expected-error{{expected the class name}}
+ x->~int(); // expected-error{{expected a class name}}
x->operator; // expected-error{{missing type specifier after 'operator'}}
x->operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 15e37c5..13ffe1b 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -18,8 +18,8 @@
a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}}
- // FIXME: the type printed below isn't wonderful
- a->~Bar(); // expected-error{{no member named}}
+ // FIXME: the diagnostic below isn't wonderful
+ a->~Bar(); // expected-error{{does not name a type}}
f->~Bar();
f->~Foo();
@@ -28,7 +28,7 @@
g().~Bar(); // expected-error{{non-scalar}}
f->::~Bar();
- f->N::~Wibble();
+ f->N::~Wibble(); // expected-error{{expected the class name after '~' to name a destructor}}
f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
}
diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp
index b5ad967..7dd429b 100644
--- a/test/SemaTemplate/destructor-template.cpp
+++ b/test/SemaTemplate/destructor-template.cpp
@@ -17,3 +17,16 @@
}
template void destroy_me(Incomplete*);
+
+namespace PR6152 {
+ template<typename T> struct X { void f(); };
+ template<typename T> struct Y { };
+ template<typename T>
+ void X<T>::f() {
+ Y<T> *y;
+ y->template Y<T>::~Y();
+ }
+
+ template struct X<int>;
+}
+