diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-14 00:28:11 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-14 00:28:11 +0000 |
commit | 2ec748cd5a66e0d8ac3c83887e5014f81e95204c (patch) | |
tree | 8028813c3ecd1d35a53eef3be7b1755a9c76a1cb /clang/test/SemaTemplate/temp_explicit.cpp | |
parent | 0e78566e0207a4cfe8a512ea667f90399f2b255a (diff) | |
download | bcm5719-llvm-2ec748cd5a66e0d8ac3c83887e5014f81e95204c.tar.gz bcm5719-llvm-2ec748cd5a66e0d8ac3c83887e5014f81e95204c.zip |
Implement explicit instantiations of member classes of class templates, e.g.,
template<typename T>
struct X {
struct Inner;
};
template struct X<int>::Inner;
This change is larger than it looks because it also fixes some
a problem with nested-name-specifiers and tags. We weren't requiring
the DeclContext associated with the scope specifier of a tag to be
complete. Therefore, when looking for something like "struct
X<int>::Inner", we weren't instantiating X<int>.
This, naturally, uncovered a problem with member pointers, where we
were requiring the left-hand side of a member pointer access
expression (e.g., x->*) to be a complete type. However, this is wrong:
the semantics of this expression does not require a complete type (EDG
agrees).
Stuart vouched for me. Blame him.
llvm-svn: 71756
Diffstat (limited to 'clang/test/SemaTemplate/temp_explicit.cpp')
-rw-r--r-- | clang/test/SemaTemplate/temp_explicit.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/temp_explicit.cpp b/clang/test/SemaTemplate/temp_explicit.cpp index 0b96c73c1f2..6394f1daf47 100644 --- a/clang/test/SemaTemplate/temp_explicit.cpp +++ b/clang/test/SemaTemplate/temp_explicit.cpp @@ -71,3 +71,41 @@ void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated template struct X4<int&>; // expected-note{{instantiation}} template struct X4<float&>; // expected-note{{instantiation}} + +// Check explicit instantiation of member classes +namespace N2 { + +template<typename T> +struct X5 { + struct Inner1 { + void f(T&); + }; + + struct Inner2 { + struct VeryInner { // expected-note 2{{instantiation}} + void g(T*); // expected-error 2{{pointer to a reference}} + }; + }; +}; + +} + +template struct N2::X5<void>::Inner2; + +using namespace N2; +template struct X5<int&>::Inner2; // expected-note{{instantiation}} + +void f4(X5<float&>::Inner2); +template struct X5<float&>::Inner2; // expected-note{{instantiation}} + +namespace N3 { + template struct N2::X5<int>::Inner2; +} + +struct X6 { + struct Inner { // expected-note{{here}} + void f(); + }; +}; + +template struct X6::Inner; // expected-error{{non-templated}} |