summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate/temp.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-02-15 21:53:07 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-02-15 21:53:07 +0000
commitafcfb6bc3a92c494bce8000651df8da7476d25f8 (patch)
tree62b002698ce995e648e68afe516db3ccffc51937 /clang/test/SemaTemplate/temp.cpp
parent9982ee5472f87059cee75146293d0742f95bacc8 (diff)
downloadbcm5719-llvm-afcfb6bc3a92c494bce8000651df8da7476d25f8.tar.gz
bcm5719-llvm-afcfb6bc3a92c494bce8000651df8da7476d25f8.zip
Fix implementation of [temp.local]p4.
When a template-name is looked up, we need to give injected-class-name declarations of class templates special treatment, as they denote a template rather than a type. Previously we achieved this by applying a filter to the lookup results after completing name lookup, but that is incorrect in various ways, not least of which is that it lost all information about access and how members were named, and the filtering caused us to generally lose all ambiguity errors between templates and non-templates. We now preserve the lookup results exactly, and the few places that need to map from a declaration found by name lookup into a declaration of a template do so explicitly. Deduplication of repeated lookup results of the same injected-class-name declaration is done by name lookup instead of after the fact. This reinstates r354091, which was previously reverted in r354097 because it exposed bugs in lldb and compiler-rt. Those bugs were fixed in r354173 and r354174 respectively. llvm-svn: 354176
Diffstat (limited to 'clang/test/SemaTemplate/temp.cpp')
-rw-r--r--clang/test/SemaTemplate/temp.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/clang/test/SemaTemplate/temp.cpp b/clang/test/SemaTemplate/temp.cpp
index e037f0f0713..a8a2daeac31 100644
--- a/clang/test/SemaTemplate/temp.cpp
+++ b/clang/test/SemaTemplate/temp.cpp
@@ -8,12 +8,43 @@ namespace test0 {
// PR7252
namespace test1 {
- namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
+ namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note 3{{member}}
namespace B { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
template<typename T> struct Derived : A::Base<char>, B::Base<int> {
- // FIXME: the syntax error here is unfortunate
- typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}} \
- // expected-error {{expected member name or ';'}}
+ typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}}
};
+
+ class X : A::Base<int> {}; // expected-note 2{{private}}
+ class Y : A::Base<float> {};
+ struct Z : A::Base<double> {};
+ struct Use1 : X, Y {
+ Base<double> b1; // expected-error {{private}}
+ Use1::Base<double> b2; // expected-error {{private}}
+ };
+ struct Use2 : Z, Y {
+ Base<double> b1;
+ Use2::Base<double> b2;
+ };
+ struct Use3 : X, Z {
+ Base<double> b1;
+ Use3::Base<double> b2;
+ };
+}
+
+namespace test2 {
+ struct A { static int x; }; // expected-note 4{{member}}
+ struct B { template<typename T> static T x(); }; // expected-note 4{{member}}
+ struct C { template<typename T> struct x {}; }; // expected-note 3{{member}}
+ struct D { template<typename T> static T x(); }; // expected-note {{member}}
+
+ template<typename ...T> struct X : T... {};
+
+ void f() {
+ X<A, B>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<B, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, B, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, B, D>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ }
}
OpenPOWER on IntegriCloud