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.
117 lines
3.4 KiB
C++
117 lines
3.4 KiB
C++
// RUN: %clang_cc1 %s -fsyntax-only -verify
|
|
|
|
namespace CurrentInstantiation {
|
|
template<typename T>
|
|
struct A0 { // expected-note 6{{definition of 'A0<T>' is not complete until the closing '}'}}
|
|
struct B0 : A0 { }; // expected-error {{base class has incomplete type}}
|
|
|
|
template<typename U>
|
|
struct B1 : A0 { }; // expected-error {{base class has incomplete type}}
|
|
|
|
struct B2;
|
|
|
|
template<typename U>
|
|
struct B3;
|
|
|
|
struct B4 { // expected-note 2{{definition of 'CurrentInstantiation::A0::B4' is not complete until the closing '}'}}
|
|
struct C0 : A0, B4 { }; // expected-error 2{{base class has incomplete type}}
|
|
|
|
template<typename V>
|
|
struct C1 : A0, B4 { }; // expected-error 2{{base class has incomplete type}}
|
|
|
|
struct C2;
|
|
|
|
template<typename V>
|
|
struct C3;
|
|
};
|
|
|
|
template<typename U>
|
|
struct B5 { // expected-note 2{{definition of 'B5<U>' is not complete until the closing '}'}}
|
|
struct C0 : A0, B5 { }; // expected-error 2{{base class has incomplete type}}
|
|
|
|
template<typename V>
|
|
struct C1 : A0, B5 { }; // expected-error 2{{base class has incomplete type}}
|
|
|
|
struct C2;
|
|
|
|
template<typename V>
|
|
struct C3;
|
|
};
|
|
};
|
|
|
|
template<typename T>
|
|
struct A0<T>::B2 : A0 { };
|
|
|
|
template<typename T>
|
|
template<typename U>
|
|
struct A0<T>::B3 : A0 { };
|
|
|
|
template<typename T>
|
|
struct A0<T>::B4::C2 : A0, B4 { };
|
|
|
|
template<typename T>
|
|
template<typename V>
|
|
struct A0<T>::B4::C3 : A0, B4 { };
|
|
|
|
template<typename T>
|
|
template<typename U>
|
|
struct A0<T>::B5<U>::C2 : A0, B5 { };
|
|
|
|
template<typename T>
|
|
template<typename U>
|
|
template<typename V>
|
|
struct A0<T>::B5<U>::C3 : A0, B5 { };
|
|
|
|
template<typename T>
|
|
struct A0<T*> { // expected-note 2{{definition of 'A0<T *>' is not complete until the closing '}'}}
|
|
struct B0 : A0 { }; // expected-error {{base class has incomplete type}}
|
|
|
|
template<typename U>
|
|
struct B1 : A0 { }; // expected-error {{base class has incomplete type}}
|
|
|
|
struct B2;
|
|
|
|
template<typename U>
|
|
struct B3;
|
|
};
|
|
|
|
template<typename T>
|
|
struct A0<T*>::B2 : A0 { };
|
|
|
|
template<typename T>
|
|
template<typename U>
|
|
struct A0<T*>::B3 : A0 { };
|
|
} // namespace CurrentInstantiation
|
|
|
|
namespace MemberOfCurrentInstantiation {
|
|
template<typename T>
|
|
struct A0 {
|
|
struct B : B { }; // expected-error {{base class has incomplete type}}
|
|
// expected-note@-1 {{definition of 'MemberOfCurrentInstantiation::A0::B' is not complete until the closing '}'}}
|
|
|
|
template<typename U>
|
|
struct C : C<U> { }; // expected-error {{base class has incomplete type}}
|
|
// expected-note@-1 {{definition of 'C<U>' is not complete until the closing '}'}}
|
|
};
|
|
|
|
template<typename T>
|
|
struct A1 {
|
|
struct B; // expected-note {{definition of 'MemberOfCurrentInstantiation::A1<long>::B' is not complete until the closing '}'}}
|
|
|
|
struct C : B { }; // expected-error {{base class has incomplete type}}
|
|
|
|
struct B : C { }; // expected-note {{in instantiation of member class 'MemberOfCurrentInstantiation::A1<long>::C' requested here}}
|
|
};
|
|
|
|
template struct A1<long>; // expected-note {{in instantiation of member class 'MemberOfCurrentInstantiation::A1<long>::B' requested here}}
|
|
|
|
template<>
|
|
struct A1<short>::B {
|
|
static constexpr bool f() {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
static_assert(A1<short>::C::f());
|
|
} // namespace MemberOfCurrentInstantiation
|