Skip to content

Commit 7f78f99

Browse files
authored
[clang] Reland: Instantiate alias templates with sugar (#101858)
This makes use of the changes introduced in D134604, in order to instantiate alias templates witn a final sugared substitution. This comes at no additional relevant cost. Since we don't track / unique them in specializations, we wouldn't be able to resugar them later anyway. Differential Revision: https://reviews.llvm.org/D136565
1 parent 7483711 commit 7f78f99

File tree

16 files changed

+77
-101
lines changed

16 files changed

+77
-101
lines changed

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,7 @@ class Foo final {})cpp";
13251325
HI.LocalScope = "";
13261326
HI.Kind = index::SymbolKind::TypeAlias;
13271327
HI.Definition = "template <typename T> using AA = A<T>";
1328-
HI.Type = {"A<T>", "type-parameter-0-0"}; // FIXME: should be 'T'
1328+
HI.Type = {"A<T>", "T"};
13291329
HI.TemplateParameters = {
13301330
{{"typename"}, std::string("T"), std::nullopt}};
13311331
}},

clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ T qux(T Generic) {
7676
async::Future<T> TemplateType;
7777
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future<T>' [bugprone-unused-local-non-trivial-variable]
7878
a::Future<T> AliasTemplateType;
79-
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'Future<type-parameter-0-0>') [bugprone-unused-local-non-trivial-variable]
79+
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'Future<T>') [bugprone-unused-local-non-trivial-variable]
8080
[[maybe_unused]] async::Future<Units> MaybeUnused;
8181
return Generic;
8282
}

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ Improvements to Clang's diagnostics
149149

150150
- -Wdangling-assignment-gsl is enabled by default.
151151
- Clang now does a better job preserving the template arguments as written when specializing concepts.
152+
- Clang now always preserves the template arguments as written used
153+
to specialize template type aliases.
152154

153155
Improvements to Clang's time-trace
154156
----------------------------------

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3334,8 +3334,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
33343334

33353335
// Only substitute for the innermost template argument list.
33363336
MultiLevelTemplateArgumentList TemplateArgLists;
3337-
TemplateArgLists.addOuterTemplateArguments(Template, CanonicalConverted,
3338-
/*Final=*/false);
3337+
TemplateArgLists.addOuterTemplateArguments(Template, SugaredConverted,
3338+
/*Final=*/true);
33393339
TemplateArgLists.addOuterRetainedLevels(
33403340
AliasTemplate->getTemplateParameters()->getDepth());
33413341

clang/test/AST/ast-dump-template-decls.cpp

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -123,48 +123,31 @@ using type2 = typename C<int>::type1<void>;
123123
// CHECK-NEXT: TemplateArgument type 'void'
124124
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
125125
// CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
126-
// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar class depth 0 index 0 U
127-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'type1'
128126
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
129127
// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T
130128
// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C'
131129
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
132130
} // namespace PR55886
133131

134132
namespace PR56099 {
135-
template <typename... As> struct Y;
136-
template <typename... Bs> using Z = Y<Bs...>;
137-
template <typename... Cs> struct foo {
138-
template <typename... Ds> using bind = Z<Ds..., Cs...>;
139-
};
140-
using t1 = foo<int, short>::bind<char, float>;
141-
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar
142-
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... Bs pack_index 3
143-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
144-
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... Bs pack_index 2
145-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
146-
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... Bs pack_index 1
147-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
148-
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... Bs pack_index 0
149-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
150-
151133
template <typename... T> struct D {
152-
template <typename... U> using B = int(int (*...p)(T, U));
134+
template <typename... U> struct bind {
135+
using bound_type = int(int (*...p)(T, U));
136+
};
153137
};
154-
using t2 = D<float, char>::B<int, short>;
155-
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias{{$}}
156-
// CHECK-NEXT: name: 'D<float, char>::B':'PR56099::D<float, char>::B' qualified
138+
template struct D<float, char>::bind<int, short>;
139+
// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:5, col:45> col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))'
157140
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
158141
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
159142
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1
160143
// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
161144
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U pack_index 1
162-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B'
145+
// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind'
163146
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl
164147
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T pack_index 0
165148
// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
166149
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U pack_index 0
167-
// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B'
150+
// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind'
168151
} // namespace PR56099
169152

170153
namespace subst_default_argument {
@@ -178,9 +161,7 @@ using test1 = D<E, int>;
178161
// CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified
179162
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
180163
// CHECK-NEXT: |-TemplateArgument type 'int'
181-
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
182-
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D'
183-
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
164+
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
184165
// CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>'
185166
// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A'
186167
} // namespace subst_default_argument

clang/test/CXX/temp/temp.deduct.guide/p3.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ template<template<typename> typename TT> struct E { // expected-note 2{{template
3333
};
3434

3535
A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
36-
template<typename T> A(T) -> B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<type-parameter-0-0>') of deduction guide is not written as a specialization of template 'A'}}
36+
template <typename T> A(T)->B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<T>') of deduction guide is not written as a specialization of template 'A'}}
3737
template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}}
3838

3939
// A deduction-guide shall be declared in the same scope as the corresponding

clang/test/Misc/diag-template-diffing-cxx11.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -257,25 +257,22 @@ int f9(S9<int, char, U9<const double>>);
257257
int k9 = f9(V9<double>());
258258

259259
// CHECK-ELIDE-NOTREE: no matching function for call to 'f9'
260-
// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<[2 * ...], S9<[2 * ...], double>>' to 'S9<[2 * ...], S9<[2 * ...], const double>>' for 1st argument
260+
// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<[2 * ...], U9<double>>' to 'S9<[2 * ...], U9<const double>>' for 1st argument
261261
// CHECK-NOELIDE-NOTREE: no matching function for call to 'f9'
262-
// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<int, char, S9<int, char, double>>' to 'S9<int, char, S9<int, char, const double>>' for 1st argument
262+
// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<int, char, U9<double>>' to 'S9<int, char, U9<const double>>' for 1st argument
263263
// CHECK-ELIDE-TREE: no matching function for call to 'f9'
264264
// CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
265265
// CHECK-ELIDE-TREE: S9<
266-
// CHECK-ELIDE-TREE: [2 * ...],
267-
// CHECK-ELIDE-TREE: S9<
268-
// CHECK-ELIDE-TREE: [2 * ...],
269-
// CHECK-ELIDE-TREE: [double != const double]>>
266+
// CHECK-ELIDE-TREE: [2 * ...],
267+
// CHECK-ELIDE-TREE: U9<
268+
// CHECK-ELIDE-TREE: [(no qualifiers) != const] double>>
270269
// CHECK-NOELIDE-TREE: no matching function for call to 'f9'
271270
// CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
272271
// CHECK-NOELIDE-TREE: S9<
273-
// CHECK-NOELIDE-TREE: int,
274-
// CHECK-NOELIDE-TREE: char,
275-
// CHECK-NOELIDE-TREE: S9<
276-
// CHECK-NOELIDE-TREE: int,
277-
// CHECK-NOELIDE-TREE: char,
278-
// CHECK-NOELIDE-TREE: [double != const double]>>
272+
// CHECK-NOELIDE-TREE: int,
273+
// CHECK-NOELIDE-TREE: char,
274+
// CHECK-NOELIDE-TREE: U9<
275+
// CHECK-NOELIDE-TREE: [(no qualifiers) != const] double>>
279276

280277
template<typename ...A> class class_types {};
281278
void set10(class_types<int, int>) {}

clang/test/SemaCXX/nullability.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void test_accepts_nonnull_null_pointer_literal(X *x) {
9898
accepts_nonnull_6(nullptr); // expected-warning{{null passed to a callee that requires a non-null argument}}
9999
}
100100

101-
template<void FP(_Nonnull int*)>
101+
template<void FP(_Nonnull int*)>
102102
void test_accepts_nonnull_null_pointer_literal_template() {
103103
FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
104104
}
@@ -197,6 +197,6 @@ void testNullabilityCompletenessWithTemplate() {
197197

198198
namespace GH60344 {
199199
class a;
200-
template <typename b> using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'GH60344::a'}}
200+
template <typename b> using c = b _Nullable; // expected-error {{'_Nullable' cannot be applied to non-pointer type 'a'}}
201201
c<a>; // expected-note {{in instantiation of template type alias 'c' requested here}}
202202
}

clang/test/SemaCXX/sizeless-1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ void template_fn_rvalue_ref(T &&) {}
325325

326326
#if __cplusplus >= 201103L
327327
template <typename T>
328-
using array_alias = T[1]; // expected-error {{array has sizeless element type '__SVInt8_t'}}
328+
using array_alias = T[1]; // expected-error {{array has sizeless element type 'svint8_t' (aka '__SVInt8_t')}}
329329
extern array_alias<int> *array_alias_int_ptr;
330330
extern array_alias<svint8_t> *array_alias_int8_ptr; // expected-note {{in instantiation of template type alias 'array_alias' requested here}}
331331
#endif

clang/test/SemaHLSL/VectorOverloadResolution.hlsl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void Fn2(int16_t2 S);
2222
// CHECK: CallExpr {{.*}} 'void'
2323
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
2424
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn2' 'void (int64_t2)'
25-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<long, 2>' <IntegralCast>
25+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int64_t, 2>' <IntegralCast>
2626
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int2':'vector<int, 2>' <LValueToRValue>
2727
// CHECK-NEXT: DeclRefExpr {{.*}} 'int2':'vector<int, 2>' lvalue ParmVar {{.*}} 'I' 'int2':'vector<int, 2>'
2828

@@ -36,7 +36,7 @@ void Fn3( int64_t2 p0);
3636
// CHECK: CallExpr {{.*}} 'void'
3737
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
3838
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
39-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<long, 2>' <FloatingToIntegral>
39+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int64_t, 2>' <FloatingToIntegral>
4040
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'vector<half, 2>' <LValueToRValue>
4141
// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'vector<half, 2>' lvalue ParmVar {{.*}} 'p0' 'half2':'vector<half, 2>'
4242
// CHECKIR-LABEL: Call3
@@ -49,7 +49,7 @@ void Call3(half2 p0) {
4949
// CHECK: CallExpr {{.*}} 'void'
5050
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' <FunctionToPointerDecay>
5151
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)'
52-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<long, 2>' <FloatingToIntegral>
52+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int64_t, 2>' <FloatingToIntegral>
5353
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'vector<float, 2>' <LValueToRValue>
5454
// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'vector<float, 2>' lvalue ParmVar {{.*}} 'p0' 'float2':'vector<float, 2>'
5555
// CHECKIR-LABEL: Call4
@@ -65,8 +65,8 @@ void Fn4( float2 p0);
6565
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' <FunctionToPointerDecay>
6666
// CHECK-NEXT: DeclRefExpr {{.*}} 'void (float2)' lvalue Function {{.*}} 'Fn4' 'void (float2)'
6767
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 2>' <IntegralToFloating>
68-
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'vector<long, 2>' <LValueToRValue>
69-
// CHECK-NEXT: DeclRefExpr {{.*}} 'int64_t2':'vector<long, 2>' lvalue ParmVar {{.*}} 'p0' 'int64_t2':'vector<long, 2>'
68+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'vector<int64_t, 2>' <LValueToRValue>
69+
// CHECK-NEXT: DeclRefExpr {{.*}} 'int64_t2':'vector<int64_t, 2>' lvalue ParmVar {{.*}} 'p0' 'int64_t2':'vector<int64_t, 2>'
7070
// CHECKIR-LABEL: Call5
7171
// CHECKIR: {{.*}} = sitofp <2 x i64> {{.*}} to <2 x float>
7272
void Call5(int64_t2 p0) {

0 commit comments

Comments
 (0)