mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-14 18:56:31 +00:00

This relands https://github.com/llvm/llvm-project/pull/135119, after fixing crashes seen in LLDB CI reported here: https://github.com/llvm/llvm-project/pull/135119#issuecomment-2794910840 Fixes https://github.com/llvm/llvm-project/pull/135119 This changes the TemplateArgument representation to hold a flag indicating whether a tempalte argument of expression type is supposed to be canonical or not. This gets one step closer to solving https://github.com/llvm/llvm-project/issues/92292 This still doesn't try to unique as-written TSTs. While this would increase the amount of memory savings and make code dealing with the AST more well-behaved, profiling template argument lists is still too expensive for this to be worthwhile, at least for now. This also fixes the context creation of TSTs, so that they don't in some cases get incorrectly flagged as sugar over their own canonical form. This is captured in the test expectation change of some AST dumps. This fixes some places which were unnecessarily canonicalizing these TSTs.
90 lines
2.7 KiB
C++
90 lines
2.7 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
|
|
|
// Test class template partial specializations of member templates.
|
|
template<typename T>
|
|
struct X0 {
|
|
template<typename U> struct Inner0 {
|
|
static const unsigned value = 0;
|
|
};
|
|
|
|
template<typename U> struct Inner0<U*> {
|
|
static const unsigned value = 1;
|
|
};
|
|
};
|
|
|
|
template<typename T> template<typename U>
|
|
struct X0<T>::Inner0<const U*> {
|
|
static const unsigned value = 2;
|
|
};
|
|
|
|
int array0[X0<int>::Inner0<int>::value == 0? 1 : -1];
|
|
int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1];
|
|
int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1];
|
|
|
|
// Make sure we can provide out-of-line class template partial specializations
|
|
// for member templates (and instantiate them).
|
|
template<class T> struct A {
|
|
struct C {
|
|
template<class T2> struct B;
|
|
};
|
|
};
|
|
|
|
// partial specialization of A<T>::C::B<T2>
|
|
template<class T> template<class T2> struct A<T>::C::B<T2*> { };
|
|
|
|
A<short>::C::B<int*> absip;
|
|
|
|
// Check for conflicts during template instantiation.
|
|
template<typename T, typename U>
|
|
struct Outer {
|
|
template<typename X, typename Y> struct Inner;
|
|
template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous declaration of class template partial specialization 'Inner<int, Y>' is here}}
|
|
template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}
|
|
};
|
|
|
|
Outer<int, int> outer; // expected-note{{instantiation}}
|
|
|
|
// Test specialization of class template partial specialization members.
|
|
template<> template<typename Z>
|
|
struct X0<float>::Inner0<Z*> {
|
|
static const unsigned value = 3;
|
|
};
|
|
|
|
int array3[X0<float>::Inner0<int>::value == 0? 1 : -1];
|
|
int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1];
|
|
int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1];
|
|
|
|
namespace rdar8651930 {
|
|
template<typename OuterT>
|
|
struct Outer {
|
|
template<typename T, typename U>
|
|
struct Inner;
|
|
|
|
template<typename T>
|
|
struct Inner<T, T> {
|
|
static const bool value = true;
|
|
};
|
|
|
|
template<typename T, typename U>
|
|
struct Inner {
|
|
static const bool value = false;
|
|
};
|
|
};
|
|
|
|
int array0[Outer<int>::Inner<int, int>::value? 1 : -1];
|
|
int array1[Outer<int>::Inner<int, float>::value? -1 : 1];
|
|
}
|
|
|
|
namespace print_dependent_TemplateSpecializationType {
|
|
|
|
template <class T, class U> struct Foo {
|
|
template <unsigned long, class X, class Y> struct Bar;
|
|
template <class Y> struct Bar<0, T, Y> {};
|
|
// expected-note-re@-1 {{previous declaration {{.*}} 'Bar<0, int, Y>' is here}}
|
|
template <class Y> struct Bar<0, U, Y> {};
|
|
// expected-error@-1 {{partial specialization 'Bar<0, int, Y>' cannot be redeclared}}
|
|
};
|
|
template struct Foo<int, int>; // expected-note {{requested here}}
|
|
|
|
} // namespace print_dependent_TemplateSpecializationType
|