mizvekov updated this revision to Diff 458621.
mizvekov marked 6 inline comments as done.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D131858/new/
https://reviews.llvm.org/D131858
Files:
clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
clang-tools-extra/clangd/AST.cpp
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/ASTNodeTraverser.h
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/AST/Type.h
clang/include/clang/AST/TypeProperties.td
clang/include/clang/Sema/Template.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/AST/Type.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaConcept.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/lib/Sema/SemaTemplateVariadic.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriterDecl.cpp
clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp
clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
clang/test/AST/ast-dump-template-decls.cpp
clang/test/AST/deduction-guides.cpp
clang/test/SemaTemplate/deduction-guide.cpp
clang/test/SemaTemplate/make_integer_seq.cpp
clang/test/SemaTemplate/type_pack_element.cpp
libcxx/DELETE.ME
Index: libcxx/DELETE.ME
===================================================================
--- libcxx/DELETE.ME
+++ libcxx/DELETE.ME
@@ -2,3 +2,4 @@
D111283
D111509
D130308
+D131858
Index: clang/test/SemaTemplate/type_pack_element.cpp
===================================================================
--- clang/test/SemaTemplate/type_pack_element.cpp
+++ clang/test/SemaTemplate/type_pack_element.cpp
@@ -11,14 +11,13 @@
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:35> 'int' 0
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
-// CHECK-NEXT: |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
-// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT: `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar typename depth 0 index 1 ...
+// CHECK-NEXT: |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__type_pack_element'
// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
template<int N, class ...Ts> struct A {
using test2 = __type_pack_element<N, Ts...>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:20:3, col:45> col:9 test2 '__type_pack_element<N, Ts...>':'__type_pack_element<N, type-parameter-0-1...>'
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:19:3, col:45> col:9 test2 '__type_pack_element<N, Ts...>':'__type_pack_element<N, type-parameter-0-1...>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
@@ -38,7 +37,7 @@
// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index 1 pack
using test3 = __type_pack_element<0, Ts...>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:40:3, col:45> col:9 test3 '__type_pack_element<0, Ts...>':'type-parameter-0-1...'
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:39:3, col:45> col:9 test3 '__type_pack_element<0, Ts...>':'type-parameter-0-1...'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
@@ -50,14 +49,13 @@
// CHECK-NEXT: | `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
-// CHECK-NEXT: `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1...' sugar dependent
-// CHECK-NEXT: |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
-// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT: `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1...' sugar dependent typename depth 0 index 1 ...
+// CHECK-NEXT: |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__type_pack_element'
// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1...' dependent
// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index
using test4 = __type_pack_element<N, int>;
-// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:59:3, col:43> col:9 test4 '__type_pack_element<N, int>':'__type_pack_element<N, int>'
+// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:57:3, col:43> col:9 test4 '__type_pack_element<N, int>':'__type_pack_element<N, int>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
Index: clang/test/SemaTemplate/make_integer_seq.cpp
===================================================================
--- clang/test/SemaTemplate/make_integer_seq.cpp
+++ clang/test/SemaTemplate/make_integer_seq.cpp
@@ -15,9 +15,8 @@
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar A
// CHECK-NEXT: |-TemplateArgument type 'int':'int'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
-// CHECK-NEXT: | |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
-// CHECK-NEXT: | | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar typename depth 0 index 1
+// CHECK-NEXT: | |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__make_integer_seq'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int'
@@ -28,7 +27,7 @@
template <class B1, B1 B2> using B = __make_integer_seq<A, B1, B2>;
using test2 = B<int, 1>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:30:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:29:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar alias B
// CHECK-NEXT: |-TemplateArgument type 'int'
@@ -41,21 +40,19 @@
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument type 'int':'int'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
-// CHECK-NEXT: | |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'B1' dependent depth 0 index 0
-// CHECK-NEXT: | | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'B1'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1
+// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:29:64> 'int'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:28:64> 'int'
// CHECK-NEXT: | |-value: Int 1
// CHECK-NEXT: | `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
// CHECK-NEXT: | |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <col:21, col:24> col:24 referenced 'B1' depth 0 index 1 B2
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 1
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar A
// CHECK-NEXT: |-TemplateArgument type 'int':'int'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
-// CHECK-NEXT: | |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
-// CHECK-NEXT: | | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar typename depth 0 index 1
+// CHECK-NEXT: | |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__make_integer_seq'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
@@ -66,7 +63,7 @@
template <template <class T, T...> class S, class T, int N> struct C {
using test3 = __make_integer_seq<S, T, N>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:68:3, col:43> col:9 test3 '__make_integer_seq<S, T, N>':'__make_integer_seq<type-parameter-0-1, N>'
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:65:3, col:43> col:9 test3 '__make_integer_seq<S, T, N>':'__make_integer_seq<type-parameter-0-1, N>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template S
@@ -85,7 +82,7 @@
// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
using test4 = __make_integer_seq<A, T, 1>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:87:3, col:43> col:9 test4 '__make_integer_seq<A, T, 1>':'__make_integer_seq<A, type-parameter-0-1, 1>'
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:84:3, col:43> col:9 test4 '__make_integer_seq<A, T, 1>':'__make_integer_seq<A, type-parameter-0-1, 1>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
@@ -104,7 +101,7 @@
// CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
using test5 = __make_integer_seq<A, int, N>;
-// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:106:3, col:45> col:9 test5 '__make_integer_seq<A, int, N>':'__make_integer_seq<A, int, N>'
+// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:103:3, col:45> col:9 test5 '__make_integer_seq<A, int, N>':'__make_integer_seq<A, int, N>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
Index: clang/test/SemaTemplate/deduction-guide.cpp
===================================================================
--- clang/test/SemaTemplate/deduction-guide.cpp
+++ clang/test/SemaTemplate/deduction-guide.cpp
@@ -156,9 +156,8 @@
// CHECK: |-BuiltinType {{.*}} 'int'
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
-// CHECK: `-SubstTemplateTypeParmPackType {{.*}} 'U' dependent contains_unexpanded_pack
-// CHECK: |-TemplateTypeParmType {{.*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack
-// CHECK: | `-TemplateTypeParm {{.*}} 'U'
+// CHECK: `-SubstTemplateTypeParmPackType {{.*}} 'U' dependent contains_unexpanded_pack typename depth 1 index 0 ... U
+// CHECK: |-TypeAliasTemplate {{.*}} 'B'
// CHECK: `-TemplateArgument pack
// CHECK: |-TemplateArgument type 'type-parameter-0-1'
// CHECK-NOT: Subst
Index: clang/test/AST/deduction-guides.cpp
===================================================================
--- clang/test/AST/deduction-guides.cpp
+++ clang/test/AST/deduction-guides.cpp
@@ -67,9 +67,8 @@
// CHECK-NEXT: ElaboratedType {{.*}} 'typename Derived<int, 1, int>::type_alias' sugar
// CHECK-NEXT: TypedefType {{.*}} 'PR48177::Base<int>::type_alias' sugar
// CHECK-NEXT: TypeAlias {{.*}} 'type_alias'
-// CHECK-NEXT: SubstTemplateTypeParmType {{.*}} 'int' sugar
-// CHECK-NEXT: TemplateTypeParmType {{.*}} 'A'
-// CHECK-NEXT: TemplateTypeParm {{.*}} 'A'
+// CHECK-NEXT: SubstTemplateTypeParmType {{.*}} 'int' sugar class depth 0 index 0 A
+// CHECK-NEXT: ClassTemplateSpecialization {{.*}} 'Base'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (Derived<T, S, A> &&, const typename Derived<T, S, A>::type_alias &) -> Derived<T, S, A>'
Index: clang/test/AST/ast-dump-template-decls.cpp
===================================================================
--- clang/test/AST/ast-dump-template-decls.cpp
+++ clang/test/AST/ast-dump-template-decls.cpp
@@ -120,12 +120,12 @@
// CHECK-NEXT: TemplateArgument type 'void'
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
// CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
-// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent depth 0 index 0
-// CHECK-NEXT: TemplateTypeParm 0x{{[^ ]*}} 'U'
+// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar class depth 0 index 0 U
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'type1'
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
-// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent depth 0 index 0
+// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T
+// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C'
+// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
} // namespace PR55886
namespace PR56099 {
@@ -136,14 +136,14 @@
};
using t1 = foo<int, short>::bind<char, float>;
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar Y
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... Bs
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... Bs
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... Bs
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... Bs
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z'
template <typename... T> struct D {
template <typename... U> using B = int(int (*...p)(T, U));
@@ -152,13 +152,13 @@
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias B
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T
+// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B'
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
-// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T
+// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
+// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U
+// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B'
} // namespace PR56099
Index: clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
===================================================================
--- clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
+++ clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
@@ -122,9 +122,8 @@
// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8:0x[a-z0-9]*]] 'float'
// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_9:0x[a-z0-9]*]] <col:22, col:29> col:29 implicit struct remove_reference
// CHECK-NEXT: | | `-TypedefDecl [[ADDR_10:0x[a-z0-9]*]] <col:55, col:67> col:67 referenced type 'float':'float'
-// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_11:0x[a-z0-9]*]] 'float' sugar
-// CHECK-NEXT: | | |-TemplateTypeParmType [[ADDR_12:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0
-// CHECK-NEXT: | | | `-TemplateTypeParm [[ADDR_13:0x[a-z0-9]*]] '_Tp'
+// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_11:0x[a-z0-9]*]] 'float' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference'
// CHECK-NEXT: | | `-BuiltinType [[ADDR_8]] 'float'
// CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_14:0x[a-z0-9]*]] <col:1, col:73> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
@@ -139,9 +138,8 @@
// CHECK-NEXT: | | `-BuiltinType [[ADDR_16:0x[a-z0-9]*]] 'short'
// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_17:0x[a-z0-9]*]] <col:22, col:29> col:29 implicit struct remove_reference
// CHECK-NEXT: | `-TypedefDecl [[ADDR_18:0x[a-z0-9]*]] <col:55, col:67> col:67 referenced type 'short':'short'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType [[ADDR_19:0x[a-z0-9]*]] 'short' sugar
-// CHECK-NEXT: | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0
-// CHECK-NEXT: | | `-TemplateTypeParm [[ADDR_13]] '_Tp'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType [[ADDR_19:0x[a-z0-9]*]] 'short' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference'
// CHECK-NEXT: | `-BuiltinType [[ADDR_16]] 'short'
// CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_20:0x[a-z0-9]*]] <col:1, col:73> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
@@ -154,10 +152,10 @@
// CHECK-NEXT: | |-TemplateArgument type 'type-parameter-0-0 &'
// CHECK-NEXT: | | `-LValueReferenceType [[ADDR_21:0x[a-z0-9]*]] 'type-parameter-0-0 &' dependent
// CHECK-NEXT: | | `-TemplateTypeParmType [[ADDR_22:0x[a-z0-9]*]] 'type-parameter-0-0' dependent depth 0 index 0
-// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_13]] <col:11, col:17> col:17 referenced class depth 0 index 0 _Tp
+// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_13:0x[a-z0-9]*]] <col:11, col:17> col:17 referenced class depth 0 index 0 _Tp
// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_23:0x[a-z0-9]*]] <col:22, col:29> col:29 implicit struct remove_reference
// CHECK-NEXT: | `-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] <col:55, col:67> col:67 type '_Tp'
-// CHECK-NEXT: | `-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0
+// CHECK-NEXT: | `-TemplateTypeParmType [[ADDR_12:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm [[ADDR_13]] '_Tp'
// CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_25:0x[a-z0-9]*]] <line:7:1, col:74> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
@@ -197,9 +195,8 @@
// CHECK-NEXT: | | | `-ElaboratedType [[ADDR_47:0x[a-z0-9]*]] 'typename remove_reference<float &>::type' sugar
// CHECK-NEXT: | | | `-TypedefType [[ADDR_48:0x[a-z0-9]*]] 'remove_reference<float &>::type' sugar
// CHECK-NEXT: | | | |-Typedef [[ADDR_10]] 'type'
-// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar
-// CHECK-NEXT: | | | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0
-// CHECK-NEXT: | | | | `-TemplateTypeParm [[ADDR_13]] '_Tp'
+// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference'
// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8]] 'float'
// CHECK-NEXT: | | `-ReturnStmt [[ADDR_49:0x[a-z0-9]*]] <line:13:3, col:33>
// CHECK-NEXT: | | `-CXXStaticCastExpr [[ADDR_50:0x[a-z0-9]*]] <col:10, col:33> '_Up':'float' xvalue static_cast<_Up &&> <NoOp>
@@ -215,9 +212,8 @@
// CHECK-NEXT: | | `-ElaboratedType [[ADDR_57:0x[a-z0-9]*]] 'typename remove_reference<short &>::type' sugar
// CHECK-NEXT: | | `-TypedefType [[ADDR_58:0x[a-z0-9]*]] 'remove_reference<short &>::type' sugar
// CHECK-NEXT: | | |-Typedef [[ADDR_18]] 'type'
-// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar
-// CHECK-NEXT: | | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0
-// CHECK-NEXT: | | | `-TemplateTypeParm [[ADDR_13]] '_Tp'
+// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference'
// CHECK-NEXT: | | `-BuiltinType [[ADDR_16]] 'short'
// CHECK-NEXT: | `-ReturnStmt [[ADDR_59:0x[a-z0-9]*]] <line:13:3, col:33>
// CHECK-NEXT: | `-CXXStaticCastExpr [[ADDR_60:0x[a-z0-9]*]] <col:10, col:33> '_Up':'short' xvalue static_cast<_Up &&> <NoOp>
Index: clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp
@@ -176,8 +176,10 @@
const auto *Param = Func->getParamDecl(J);
const auto *ParamType =
Param->getType()->getAs<SubstTemplateTypeParmType>();
- if (!ParamType ||
- ParamType->getReplacedParameter()->getDecl() != TPDecl)
+ if (!ParamType)
+ continue;
+ const TemplateTypeParmDecl *D = ParamType->getReplacedParameter();
+ if (D != TPDecl)
continue;
if (LHS.isUndef()) {
LHS = Call.getArgSVal(J);
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -540,46 +540,6 @@
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitRedeclarable(D);
- VisitDeclaratorDecl(D);
- Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
- Record.push_back(D->getIdentifierNamespace());
-
- // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
- // after everything else is written.
- Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
- Record.push_back(D->isInlineSpecified());
- Record.push_back(D->isInlined());
- Record.push_back(D->isVirtualAsWritten());
- Record.push_back(D->isPure());
- Record.push_back(D->hasInheritedPrototype());
- Record.push_back(D->hasWrittenPrototype());
- Record.push_back(D->isDeletedBit());
- Record.push_back(D->isTrivial());
- Record.push_back(D->isTrivialForCall());
- Record.push_back(D->isDefaulted());
- Record.push_back(D->isExplicitlyDefaulted());
- Record.push_back(D->hasImplicitReturnZero());
- Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
- Record.push_back(D->usesSEHTry());
- Record.push_back(D->hasSkippedBody());
- Record.push_back(D->isMultiVersion());
- Record.push_back(D->isLateTemplateParsed());
- Record.push_back(D->getLinkageInternal());
- Record.AddSourceLocation(D->getEndLoc());
-
- Record.push_back(D->getODRHash());
-
- if (D->isDefaulted()) {
- if (auto *FDI = D->getDefaultedFunctionInfo()) {
- Record.push_back(FDI->getUnqualifiedLookups().size());
- for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
- Record.AddDeclRef(P.getDecl());
- Record.push_back(P.getAccess());
- }
- } else {
- Record.push_back(0);
- }
- }
Record.push_back(D->getTemplatedKind());
switch (D->getTemplatedKind()) {
@@ -660,6 +620,48 @@
}
}
+ VisitDeclaratorDecl(D);
+ Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
+ Record.push_back(D->getIdentifierNamespace());
+
+ // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
+ // after everything else is written.
+ Record.push_back(
+ static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
+ Record.push_back(D->isInlineSpecified());
+ Record.push_back(D->isInlined());
+ Record.push_back(D->isVirtualAsWritten());
+ Record.push_back(D->isPure());
+ Record.push_back(D->hasInheritedPrototype());
+ Record.push_back(D->hasWrittenPrototype());
+ Record.push_back(D->isDeletedBit());
+ Record.push_back(D->isTrivial());
+ Record.push_back(D->isTrivialForCall());
+ Record.push_back(D->isDefaulted());
+ Record.push_back(D->isExplicitlyDefaulted());
+ Record.push_back(D->hasImplicitReturnZero());
+ Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
+ Record.push_back(D->usesSEHTry());
+ Record.push_back(D->hasSkippedBody());
+ Record.push_back(D->isMultiVersion());
+ Record.push_back(D->isLateTemplateParsed());
+ Record.push_back(D->getLinkageInternal());
+ Record.AddSourceLocation(D->getEndLoc());
+
+ Record.push_back(D->getODRHash());
+
+ if (D->isDefaulted()) {
+ if (auto *FDI = D->getDefaultedFunctionInfo()) {
+ Record.push_back(FDI->getUnqualifiedLookups().size());
+ for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
+ Record.AddDeclRef(P.getDecl());
+ Record.push_back(P.getAccess());
+ }
+ } else {
+ Record.push_back(0);
+ }
+ }
+
Record.push_back(D->param_size());
for (auto *P : D->parameters())
Record.AddDeclRef(P);
@@ -1404,14 +1406,12 @@
}
if (D->getDeclContext() == D->getLexicalDeclContext() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->hasAttrs() &&
- !D->isTopLevelDeclInObjCContainer() &&
+ D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
+ !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() &&
- !D->hasInheritedPrototype() &&
- D->hasWrittenPrototype())
+ !D->hasExtInfo() && !D->hasInheritedPrototype() &&
+ D->hasWrittenPrototype() &&
+ D->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
Code = serialization::DECL_CXX_METHOD;
@@ -1607,8 +1607,6 @@
VarTemplateSpecializationDecl *D) {
RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
- VisitVarDecl(D);
-
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
InstFrom = D->getSpecializedTemplateOrPartial();
if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
@@ -1629,6 +1627,9 @@
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
Record.push_back(D->IsCompleteDefinition);
+
+ VisitVarDecl(D);
+
Record.push_back(D->isCanonicalDecl());
if (D->isCanonicalDecl()) {
@@ -2233,6 +2234,8 @@
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
// RedeclarableDecl
Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
+ // FIXME: Implement abbreviation for other template kinds.
+ Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
@@ -2278,11 +2281,10 @@
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
// This Array slurps the rest of the record. Fortunately we want to encode
// (nearly) all the remaining (variable number of) fields in the same way.
//
- // This is the function template information if any, then
+ // This is:
// NumParams and Params[] from FunctionDecl, and
// NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
//
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -886,75 +886,18 @@
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
RedeclarableResult Redecl = VisitRedeclarable(FD);
- VisitDeclaratorDecl(FD);
-
- // Attach a type to this function. Use the real type if possible, but fall
- // back to the type as written if it involves a deduced return type.
- if (FD->getTypeSourceInfo() &&
- FD->getTypeSourceInfo()->getType()->castAs<FunctionType>()
- ->getReturnType()->getContainedAutoType()) {
- // We'll set up the real type in Visit, once we've finished loading the
- // function.
- FD->setType(FD->getTypeSourceInfo()->getType());
- Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
- } else {
- FD->setType(Reader.GetType(DeferredTypeID));
- }
- DeferredTypeID = 0;
- FD->DNLoc = Record.readDeclarationNameLoc(FD->getDeclName());
- FD->IdentifierNamespace = Record.readInt();
-
- // FunctionDecl's body is handled last at ASTDeclReader::Visit,
- // after everything else is read.
-
- FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
- FD->setInlineSpecified(Record.readInt());
- FD->setImplicitlyInline(Record.readInt());
- FD->setVirtualAsWritten(Record.readInt());
- // We defer calling `FunctionDecl::setPure()` here as for methods of
- // `CXXTemplateSpecializationDecl`s, we may not have connected up the
- // definition (which is required for `setPure`).
- const bool Pure = Record.readInt();
- FD->setHasInheritedPrototype(Record.readInt());
- FD->setHasWrittenPrototype(Record.readInt());
- FD->setDeletedAsWritten(Record.readInt());
- FD->setTrivial(Record.readInt());
- FD->setTrivialForCall(Record.readInt());
- FD->setDefaulted(Record.readInt());
- FD->setExplicitlyDefaulted(Record.readInt());
- FD->setHasImplicitReturnZero(Record.readInt());
- FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt()));
- FD->setUsesSEHTry(Record.readInt());
- FD->setHasSkippedBody(Record.readInt());
- FD->setIsMultiVersion(Record.readInt());
- FD->setLateTemplateParsed(Record.readInt());
-
- FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
- FD->EndRangeLoc = readSourceLocation();
-
- FD->ODRHash = Record.readInt();
- FD->setHasODRHash(true);
-
- if (FD->isDefaulted()) {
- if (unsigned NumLookups = Record.readInt()) {
- SmallVector<DeclAccessPair, 8> Lookups;
- for (unsigned I = 0; I != NumLookups; ++I) {
- NamedDecl *ND = Record.readDeclAs<NamedDecl>();
- AccessSpecifier AS = (AccessSpecifier)Record.readInt();
- Lookups.push_back(DeclAccessPair::make(ND, AS));
- }
- FD->setDefaultedFunctionInfo(FunctionDecl::DefaultedFunctionInfo::Create(
- Reader.getContext(), Lookups));
- }
- }
+ struct {
+ bool DoIt;
+ FunctionDecl *Existing = nullptr;
+ } Merge = {false};
switch ((FunctionDecl::TemplatedKind)Record.readInt()) {
case FunctionDecl::TK_NonTemplate:
- mergeRedeclarable(FD, Redecl);
+ Merge = {true};
break;
case FunctionDecl::TK_DependentNonTemplate:
- mergeRedeclarable(FD, Redecl);
+ Merge = {true};
FD->setInstantiatedFromDecl(readDeclAs<FunctionDecl>());
break;
case FunctionDecl::TK_FunctionTemplate:
@@ -967,7 +910,7 @@
SourceLocation POI = readSourceLocation();
FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
- mergeRedeclarable(FD, Redecl);
+ Merge = {true};
break;
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
@@ -1038,7 +981,7 @@
else {
assert(Reader.getContext().getLangOpts().Modules &&
"already deserialized this template specialization");
- mergeRedeclarable(FD, ExistingInfo->getFunction(), Redecl);
+ Merge = {true, ExistingInfo->getFunction()};
}
}
break;
@@ -1066,6 +1009,78 @@
}
}
+ VisitDeclaratorDecl(FD);
+
+ // Attach a type to this function. Use the real type if possible, but fall
+ // back to the type as written if it involves a deduced return type.
+ if (FD->getTypeSourceInfo() && FD->getTypeSourceInfo()
+ ->getType()
+ ->castAs<FunctionType>()
+ ->getReturnType()
+ ->getContainedAutoType()) {
+ // We'll set up the real type in Visit, once we've finished loading the
+ // function.
+ FD->setType(FD->getTypeSourceInfo()->getType());
+ Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
+ } else {
+ FD->setType(Reader.GetType(DeferredTypeID));
+ }
+ DeferredTypeID = 0;
+
+ FD->DNLoc = Record.readDeclarationNameLoc(FD->getDeclName());
+ FD->IdentifierNamespace = Record.readInt();
+
+ // FunctionDecl's body is handled last at ASTDeclReader::Visit,
+ // after everything else is read.
+
+ FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
+ FD->setInlineSpecified(Record.readInt());
+ FD->setImplicitlyInline(Record.readInt());
+ FD->setVirtualAsWritten(Record.readInt());
+ // We defer calling `FunctionDecl::setPure()` here as for methods of
+ // `CXXTemplateSpecializationDecl`s, we may not have connected up the
+ // definition (which is required for `setPure`).
+ const bool Pure = Record.readInt();
+ FD->setHasInheritedPrototype(Record.readInt());
+ FD->setHasWrittenPrototype(Record.readInt());
+ FD->setDeletedAsWritten(Record.readInt());
+ FD->setTrivial(Record.readInt());
+ FD->setTrivialForCall(Record.readInt());
+ FD->setDefaulted(Record.readInt());
+ FD->setExplicitlyDefaulted(Record.readInt());
+ FD->setHasImplicitReturnZero(Record.readInt());
+ FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt()));
+ FD->setUsesSEHTry(Record.readInt());
+ FD->setHasSkippedBody(Record.readInt());
+ FD->setIsMultiVersion(Record.readInt());
+ FD->setLateTemplateParsed(Record.readInt());
+
+ FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
+ FD->EndRangeLoc = readSourceLocation();
+
+ FD->ODRHash = Record.readInt();
+ FD->setHasODRHash(true);
+
+ if (FD->isDefaulted()) {
+ if (unsigned NumLookups = Record.readInt()) {
+ SmallVector<DeclAccessPair, 8> Lookups;
+ for (unsigned I = 0; I != NumLookups; ++I) {
+ NamedDecl *ND = Record.readDeclAs<NamedDecl>();
+ AccessSpecifier AS = (AccessSpecifier)Record.readInt();
+ Lookups.push_back(DeclAccessPair::make(ND, AS));
+ }
+ FD->setDefaultedFunctionInfo(FunctionDecl::DefaultedFunctionInfo::Create(
+ Reader.getContext(), Lookups));
+ }
+ }
+
+ if (Merge.DoIt) {
+ if (Merge.Existing)
+ mergeRedeclarable(FD, Merge.Existing, Redecl);
+ else
+ mergeRedeclarable(FD, Redecl);
+ }
+
// Defer calling `setPure` until merging above has guaranteed we've set
// `DefinitionData` (as this will need to access it).
FD->setPure(Pure);
@@ -2390,8 +2405,6 @@
ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
VarTemplateSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitVarDeclImpl(D);
-
ASTContext &C = Reader.getContext();
if (Decl *InstD = readDecl()) {
if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
@@ -2428,6 +2441,8 @@
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
D->IsCompleteDefinition = Record.readInt();
+ RedeclarableResult Redecl = VisitVarDeclImpl(D);
+
bool writtenAsCanonicalDecl = Record.readInt();
if (writtenAsCanonicalDecl) {
auto *CanonPattern = readDeclAs<VarTemplateDecl>();
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -4852,7 +4852,8 @@
Replacement = SemaRef.Context.getQualifiedType(
Replacement.getUnqualifiedType(), Qs);
T = SemaRef.Context.getSubstTemplateTypeParmType(
- SubstTypeParam->getReplacedParameter(), Replacement);
+ Replacement, SubstTypeParam->getReplacedDecl(),
+ SubstTypeParam->getIndex());
} else if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
// 'auto' types behave the same way as template parameters.
QualType Deduced = AutoTy->getDeducedType();
@@ -6399,6 +6400,9 @@
SubstTemplateTypeParmTypeLoc TL) {
const SubstTemplateTypeParmType *T = TL.getTypePtr();
+ Decl *NewReplaced =
+ getDerived().TransformDecl(TL.getNameLoc(), T->getReplacedDecl());
+
// Substitute into the replacement type, which itself might involve something
// that needs to be transformed. This only tends to occur with default
// template arguments of template template parameters.
@@ -6409,9 +6413,8 @@
// Always canonicalize the replacement type.
Replacement = SemaRef.Context.getCanonicalType(Replacement);
- QualType Result
- = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(),
- Replacement);
+ QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
+ Replacement, NewReplaced, T->getIndex());
// Propagate type-source information.
SubstTemplateTypeParmTypeLoc NewTL
Index: clang/lib/Sema/SemaTemplateVariadic.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateVariadic.cpp
+++ clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -720,7 +720,7 @@
} else if (const auto *STP =
P.dyn_cast<const SubstTemplateTypeParmPackType *>()) {
NewPackSize = STP->getNumArgs();
- ND = STP->getReplacedParameter()->getDecl();
+ ND = STP->getReplacedParameter();
} else {
const auto *SEP = P.get<const SubstNonTypeTemplateParmPackExpr *>();
NewPackSize = SEP->getArgumentPack().pack_size();
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4775,7 +4775,7 @@
return nullptr;
ContextRAII SavedContext(*this, FD);
- MultiLevelTemplateArgumentList MArgs(*Args);
+ MultiLevelTemplateArgumentList MArgs(FTD, Args->asArray());
return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs));
}
@@ -5121,9 +5121,6 @@
if (Inst.isInvalid())
return nullptr;
- MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(&TemplateArgList);
-
// Instantiate the first declaration of the variable template: for a partial
// specialization of a static data member template, the first declaration may
// or may not be the declaration in the class; if it's in the class, we want
@@ -5142,7 +5139,8 @@
if (!IsMemberSpec)
FromVar = FromVar->getFirstDecl();
- MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList);
+ MultiLevelTemplateArgumentList MultiLevelList(VarTemplate,
+ TemplateArgList.asArray());
TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(),
MultiLevelList);
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -64,7 +64,8 @@
MultiLevelTemplateArgumentList Result;
if (Innermost)
- Result.addOuterTemplateArguments(Innermost);
+ Result.addOuterTemplateArguments(const_cast<NamedDecl *>(D),
+ Innermost->asArray());
const auto *Ctx = dyn_cast<DeclContext>(D);
if (!Ctx) {
@@ -80,8 +81,6 @@
!isa<VarTemplatePartialSpecializationDecl>(Spec))
return Result;
- Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
-
// If this variable template specialization was instantiated from a
// specialized member that is a variable template, we're done.
assert(Spec->getSpecializedTemplate() && "No variable template?");
@@ -90,10 +89,14 @@
= Spec->getSpecializedTemplateOrPartial();
if (VarTemplatePartialSpecializationDecl *Partial =
Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ Result.addOuterTemplateArguments(
+ Partial, Spec->getTemplateInstantiationArgs().asArray());
if (Partial->isMemberSpecialization())
return Result;
} else {
VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
+ Result.addOuterTemplateArguments(
+ Tmpl, Spec->getTemplateInstantiationArgs().asArray());
if (Tmpl->isMemberSpecialization())
return Result;
}
@@ -123,7 +126,9 @@
!isa<ClassTemplatePartialSpecializationDecl>(Spec))
break;
- Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
+ Result.addOuterTemplateArguments(
+ const_cast<ClassTemplateSpecializationDecl *>(Spec),
+ Spec->getTemplateInstantiationArgs().asArray());
// If this class template specialization was instantiated from a
// specialized member that is a class template, we're done.
@@ -146,7 +151,8 @@
} else if (const TemplateArgumentList *TemplateArgs
= Function->getTemplateSpecializationArgs()) {
// Add the template arguments for this specialization.
- Result.addOuterTemplateArguments(TemplateArgs);
+ Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
+ TemplateArgs->asArray());
// If this function was instantiated from a specialized member that is
// a function template, we're done.
@@ -1813,6 +1819,8 @@
return NewT;
}
+ Decl *ReplacedDecl = TemplateArgs.getReplacedDecl(T->getDepth());
+
if (T->isParameterPack()) {
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
@@ -1821,8 +1829,8 @@
// We have the template argument pack, but we're not expanding the
// enclosing pack expansion yet. Just save the template argument
// pack for later substitution.
- QualType Result
- = getSema().Context.getSubstTemplateTypeParmPackType(T, Arg);
+ QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(
+ ReplacedDecl, T->getIndex(), Arg);
SubstTemplateTypeParmPackTypeLoc NewTL
= TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
@@ -1838,8 +1846,8 @@
QualType Replacement = Arg.getAsType();
// TODO: only do this uniquing once, at the start of instantiation.
- QualType Result
- = getSema().Context.getSubstTemplateTypeParmType(T, Replacement);
+ QualType Result = getSema().Context.getSubstTemplateTypeParmType(
+ Replacement, ReplacedDecl, T->getIndex());
SubstTemplateTypeParmTypeLoc NewTL
= TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
@@ -1853,8 +1861,7 @@
TemplateTypeParmDecl *NewTTPDecl = nullptr;
if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
- TransformDecl(TL.getNameLoc(), OldTTPDecl));
-
+ TransformDecl(TL.getNameLoc(), OldTTPDecl));
QualType Result = getSema().Context.getTemplateTypeParmType(
T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
T->isParameterPack(), NewTTPDecl);
@@ -1863,27 +1870,31 @@
return Result;
}
-QualType
-TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
- TypeLocBuilder &TLB,
- SubstTemplateTypeParmPackTypeLoc TL) {
+QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
+ TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL) {
+ const SubstTemplateTypeParmPackType *T = TL.getTypePtr();
+
+ Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getReplacedDecl());
+
if (getSema().ArgumentPackSubstitutionIndex == -1) {
// We aren't expanding the parameter pack, so just return ourselves.
- SubstTemplateTypeParmPackTypeLoc NewTL
- = TLB.push<SubstTemplateTypeParmPackTypeLoc>(TL.getType());
+ QualType Result = TL.getType();
+ if (NewReplaced != T->getReplacedDecl())
+ Result = getSema().Context.getSubstTemplateTypeParmPackType(
+ NewReplaced, T->getIndex(), T->getArgumentPack());
+ SubstTemplateTypeParmPackTypeLoc NewTL =
+ TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
- return TL.getType();
+ return Result;
}
- TemplateArgument Arg = TL.getTypePtr()->getArgumentPack();
- Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
- QualType Result = Arg.getAsType();
+ TemplateArgument Arg =
+ getPackSubstitutedTemplateArgument(getSema(), T->getArgumentPack());
- Result = getSema().Context.getSubstTemplateTypeParmType(
- TL.getTypePtr()->getReplacedParameter(),
- Result);
- SubstTemplateTypeParmTypeLoc NewTL
- = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
+ QualType Result = getSema().Context.getSubstTemplateTypeParmType(
+ Arg.getAsType(), NewReplaced, T->getIndex());
+ SubstTemplateTypeParmTypeLoc NewTL =
+ TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2692,7 +2692,7 @@
if (PackedArgsBuilder.empty()) {
LocalInstantiationScope Scope(S);
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
- MultiLevelTemplateArgumentList Args(TemplateArgs);
+ MultiLevelTemplateArgumentList Args(Template, TemplateArgs.asArray());
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
@@ -2864,7 +2864,7 @@
// FIXME: This will change quite a bit once deferred concept instantiation is
// implemented.
MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(DeducedArgs);
+ MLTAL.addOuterTemplateArguments(Template, DeducedArgs);
if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints,
MLTAL, Info.getLocation(),
@@ -2919,9 +2919,10 @@
TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
PartialTemplArgInfo->RAngleLoc);
- if (S.SubstTemplateArguments(
- PartialTemplArgInfo->arguments(),
- MultiLevelTemplateArgumentList(*DeducedArgumentList), InstArgs)) {
+ if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(),
+ MultiLevelTemplateArgumentList(
+ Partial, DeducedArgumentList->asArray()),
+ InstArgs)) {
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
if (ParamIdx >= Partial->getTemplateParameters()->size())
ParamIdx = Partial->getTemplateParameters()->size() - 1;
@@ -3258,7 +3259,8 @@
if (Proto->hasTrailingReturn()) {
if (SubstParmTypes(Function->getLocation(), Function->parameters(),
Proto->getExtParameterInfosOrNull(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+ MultiLevelTemplateArgumentList(
+ FunctionTemplate, ExplicitArgumentList->asArray()),
ParamTypes, /*params*/ nullptr, ExtParamInfos))
return TDK_SubstitutionFailure;
}
@@ -3284,7 +3286,8 @@
ResultType =
SubstType(Proto->getReturnType(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+ MultiLevelTemplateArgumentList(
+ FunctionTemplate, ExplicitArgumentList->asArray()),
Function->getTypeSpecStartLoc(), Function->getDeclName());
if (ResultType.isNull() || Trap.hasErrorOccurred())
return TDK_SubstitutionFailure;
@@ -3302,7 +3305,8 @@
if (!Proto->hasTrailingReturn() &&
SubstParmTypes(Function->getLocation(), Function->parameters(),
Proto->getExtParameterInfosOrNull(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+ MultiLevelTemplateArgumentList(
+ FunctionTemplate, ExplicitArgumentList->asArray()),
ParamTypes, /*params*/ nullptr, ExtParamInfos))
return TDK_SubstitutionFailure;
@@ -3317,7 +3321,8 @@
if (getLangOpts().CPlusPlus17 &&
SubstExceptionSpec(
Function->getLocation(), EPI.ExceptionSpec, ExceptionStorage,
- MultiLevelTemplateArgumentList(*ExplicitArgumentList)))
+ MultiLevelTemplateArgumentList(FunctionTemplate,
+ ExplicitArgumentList->asArray())))
return TDK_SubstitutionFailure;
*FunctionType = BuildFunctionType(ResultType, ParamTypes,
@@ -3557,7 +3562,8 @@
DeclContext *Owner = FunctionTemplate->getDeclContext();
if (FunctionTemplate->getFriendObjectKind())
Owner = FunctionTemplate->getLexicalDeclContext();
- MultiLevelTemplateArgumentList SubstArgs(*DeducedArgumentList);
+ MultiLevelTemplateArgumentList SubstArgs(FunctionTemplate,
+ DeducedArgumentList->asArray());
Specialization = cast_or_null<FunctionDecl>(
SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs));
if (!Specialization || Specialization->isInvalidDecl())
@@ -4614,7 +4620,7 @@
/*PartialTemplateArgs=*/false, Converted))
return true;
MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(Converted);
+ MLTAL.addOuterTemplateArguments(Concept, Converted);
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
MLTAL, TypeLoc.getLocalSourceRange(),
Satisfaction))
@@ -5886,9 +5892,8 @@
case Type::SubstTemplateTypeParmPack: {
const SubstTemplateTypeParmPackType *Subst
= cast<SubstTemplateTypeParmPackType>(T);
- MarkUsedTemplateParameters(Ctx,
- QualType(Subst->getReplacedParameter(), 0),
- OnlyDeduced, Depth, Used);
+ if (Subst->getReplacedParameter()->getDepth() == Depth)
+ Used[Subst->getIndex()] = true;
MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(),
OnlyDeduced, Depth, Used);
break;
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3506,11 +3506,8 @@
// Wrap the type in substitution sugar.
auto getSubstType = [&](unsigned IndexReplaced, QualType Replacement) {
- QualType TTP = SemaRef.Context.getTemplateTypeParmType(
- 0, IndexReplaced, false,
- cast<TemplateTypeParmDecl>(TPL->getParam(IndexReplaced)));
return SemaRef.Context.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(TTP), Replacement.getCanonicalType());
+ Replacement.getCanonicalType(), BTD, IndexReplaced);
};
switch (BTD->getBuiltinTemplateKind()) {
@@ -3791,7 +3788,8 @@
// Only substitute for the innermost template argument list.
MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(&StackTemplateArgs);
+ TemplateArgLists.addOuterTemplateArguments(Template,
+ StackTemplateArgs.asArray());
TemplateArgLists.addOuterRetainedLevels(
AliasTemplate->getTemplateParameters()->getDepth());
@@ -3916,7 +3914,7 @@
InstantiatingTemplate Inst(*this, TemplateLoc, Decl);
if (!Inst.isInvalid()) {
MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(Converted);
+ TemplateArgLists.addOuterTemplateArguments(Template, Converted);
InstantiateAttrsForDecl(TemplateArgLists,
ClassTemplate->getTemplatedDecl(), Decl);
}
@@ -4785,7 +4783,7 @@
TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs,
Converted);
MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(Converted);
+ MLTAL.addOuterTemplateArguments(NamedConcept, Converted);
LocalInstantiationScope Scope(*this);
if (!AreArgsDependent &&
CheckConstraintSatisfaction(
@@ -5195,8 +5193,8 @@
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
// Only substitute for the innermost template argument list.
- MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(&TemplateArgs);
+ MultiLevelTemplateArgumentList TemplateArgLists(Template,
+ TemplateArgs.asArray());
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
TemplateArgLists.addOuterTemplateArguments(None);
@@ -5251,8 +5249,8 @@
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
// Only substitute for the innermost template argument list.
- MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(&TemplateArgs);
+ MultiLevelTemplateArgumentList TemplateArgLists(Template,
+ TemplateArgs.asArray());
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
TemplateArgLists.addOuterTemplateArguments(None);
@@ -5304,8 +5302,8 @@
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
// Only substitute for the innermost template argument list.
- MultiLevelTemplateArgumentList TemplateArgLists;
- TemplateArgLists.addOuterTemplateArguments(&TemplateArgs);
+ MultiLevelTemplateArgumentList TemplateArgLists(Template,
+ TemplateArgs.asArray());
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
TemplateArgLists.addOuterTemplateArguments(None);
@@ -5489,18 +5487,15 @@
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted);
+ MultiLevelTemplateArgumentList MLTAL(Template, TemplateArgs.asArray());
// If the parameter is a pack expansion, expand this slice of the pack.
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this,
ArgumentPackIndex);
- NTTPType = SubstType(PET->getPattern(),
- MultiLevelTemplateArgumentList(TemplateArgs),
- NTTP->getLocation(),
+ NTTPType = SubstType(PET->getPattern(), MLTAL, NTTP->getLocation(),
NTTP->getDeclName());
} else {
- NTTPType = SubstType(NTTPType,
- MultiLevelTemplateArgumentList(TemplateArgs),
- NTTP->getLocation(),
+ NTTPType = SubstType(NTTPType, MLTAL, NTTP->getLocation(),
NTTP->getDeclName());
}
@@ -5643,15 +5638,15 @@
{
// Set up a template instantiation context.
LocalInstantiationScope Scope(*this);
- InstantiatingTemplate Inst(*this, TemplateLoc, Template,
- TempParm, Converted,
- SourceRange(TemplateLoc, RAngleLoc));
+ InstantiatingTemplate Inst(*this, TemplateLoc, Template, TempParm,
+ Converted, SourceRange(TemplateLoc, RAngleLoc));
if (Inst.isInvalid())
return true;
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
- Params = SubstTemplateParams(Params, CurContext,
- MultiLevelTemplateArgumentList(TemplateArgs));
+ Params = SubstTemplateParams(
+ Params, CurContext,
+ MultiLevelTemplateArgumentList(Template, TemplateArgs.asArray()));
if (!Params)
return true;
}
@@ -6013,7 +6008,7 @@
// FIXME: This will be changed a bit once deferred concept instantiation is
// implemented.
MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(Converted);
+ MLTAL.addOuterTemplateArguments(Template, Converted);
if (EnsureTemplateArgumentListConstraints(
Template, MLTAL,
SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) {
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -8925,13 +8925,13 @@
Context.getReferenceQualifiedType(E).getCanonicalType();
llvm::SmallVector<TemplateArgument, 1> Args;
Args.push_back(TemplateArgument(MatchedType));
+
+ auto *Param = cast<TemplateTypeParmDecl>(TPL->getParam(0));
+
TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args);
- MultiLevelTemplateArgumentList MLTAL(TAL);
- for (unsigned I = 0; I < TPL->getDepth(); ++I)
- MLTAL.addOuterRetainedLevel();
- Expr *IDC =
- cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint()
- ->getImmediatelyDeclaredConstraint();
+ MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray());
+ MLTAL.addOuterRetainedLevels(TPL->getDepth());
+ Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint();
ExprResult Constraint = SubstExpr(IDC, MLTAL);
if (Constraint.isInvalid()) {
Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure;
Index: clang/lib/Sema/SemaConcept.cpp
===================================================================
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -327,8 +327,9 @@
// has no access to the MultiLevelTemplateArgumentList, so this has to happen
// here.
llvm::SmallVector<TemplateArgument, 4> FlattenedArgs;
- for (ArrayRef<TemplateArgument> List : TemplateArgsLists)
- FlattenedArgs.insert(FlattenedArgs.end(), List.begin(), List.end());
+ for (auto List : TemplateArgsLists)
+ FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
+ List.Args.end());
llvm::FoldingSetNodeID ID;
ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
@@ -435,7 +436,7 @@
MultiLevelTemplateArgumentList MLTAL;
// FIXME: This will be replaced with some logic to get all the template
// arguments when we switch to deferred template instantiation.
- MLTAL.addOuterTemplateArguments(TemplateArgs);
+ MLTAL.addOuterTemplateArguments(Decl, TemplateArgs);
// If this is not an explicit specialization - we need to get the instantiated
// version of the template arguments and add them to scope for the
@@ -447,7 +448,7 @@
if (Inst.isInvalid())
return true;
MultiLevelTemplateArgumentList MLTAL(
- *Decl->getTemplateSpecializationArgs());
+ Decl, Decl->getTemplateSpecializationArgs()->asArray());
if (addInstantiatedParametersToScope(
Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL))
return true;
@@ -749,7 +750,7 @@
AtomicConstraint &Atomic = *N.getAtomicConstraint();
TemplateArgumentListInfo SubstArgs;
MultiLevelTemplateArgumentList MLTAL;
- MLTAL.addOuterTemplateArguments(TemplateArgs);
+ MLTAL.addOuterTemplateArguments(Concept, TemplateArgs);
if (!Atomic.ParameterMapping) {
llvm::SmallBitVector OccurringIndices(TemplateParams->size());
S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1462,14 +1462,27 @@
const SubstTemplateTypeParmPackType *T,
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
- printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
+ if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
+ if (D && D->isImplicit()) {
+ if (auto *TC = D->getTypeConstraint()) {
+ TC->print(OS, Policy);
+ OS << ' ';
+ }
+ OS << "auto";
+ } else if (IdentifierInfo *Id = D->getIdentifier())
+ OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
+ : Id->getName());
+ else
+ OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
+
+ spaceBeforePlaceHolder(OS);
+ }
}
void TypePrinter::printSubstTemplateTypeParmPackAfter(
const SubstTemplateTypeParmPackType *T,
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
- printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
}
void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -1166,8 +1166,8 @@
== T->getReplacementType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),
- replacementType);
+ return Ctx.getSubstTemplateTypeParmType(
+ replacementType, T->getReplacedDecl(), T->getIndex());
}
// FIXME: Non-trivial to implement, but important for C++
@@ -3649,14 +3649,105 @@
return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier();
}
+static const TemplateParameterList *
+getReplacedTemplateParameterList(const Decl *D) {
+ switch (D->getKind()) {
+ case Decl::Kind::ClassTemplate:
+ return cast<ClassTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::ClassTemplateSpecialization: {
+ const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
+ auto P = CTSD->getSpecializedTemplateOrPartial();
+ if (const auto *CTPSD =
+ P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
+ return CTPSD->getTemplateParameters();
+ return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
+ }
+ case Decl::Kind::ClassTemplatePartialSpecialization:
+ return cast<ClassTemplatePartialSpecializationDecl>(D)
+ ->getTemplateParameters();
+ case Decl::Kind::TypeAliasTemplate:
+ return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::BuiltinTemplate:
+ return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::CXXDeductionGuide:
+ case Decl::Kind::CXXConversion:
+ case Decl::Kind::CXXConstructor:
+ case Decl::Kind::CXXDestructor:
+ case Decl::Kind::CXXMethod:
+ case Decl::Kind::Function:
+ return cast<FunctionDecl>(D)
+ ->getTemplateSpecializationInfo()
+ ->getTemplate()
+ ->getTemplateParameters();
+ case Decl::Kind::FunctionTemplate:
+ return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::VarTemplate:
+ return cast<VarTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::VarTemplateSpecialization: {
+ const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
+ auto P = VTSD->getSpecializedTemplateOrPartial();
+ if (const auto *VTPSD =
+ P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
+ return VTPSD->getTemplateParameters();
+ return cast<VarTemplateDecl *>(P)->getTemplateParameters();
+ }
+ case Decl::Kind::VarTemplatePartialSpecialization:
+ return cast<VarTemplatePartialSpecializationDecl>(D)
+ ->getTemplateParameters();
+ case Decl::Kind::TemplateTemplateParm:
+ return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
+ case Decl::Kind::Concept:
+ return cast<ConceptDecl>(D)->getTemplateParameters();
+ default:
+ D->dumpColor();
+ llvm_unreachable("Unhandled templated declaration kind");
+ }
+}
+
+static const TemplateTypeParmDecl *getReplacedParameter(const Decl *D,
+ unsigned Index) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
+ return TTP;
+ return cast<TemplateTypeParmDecl>(
+ getReplacedTemplateParameterList(D)->getParam(Index));
+}
+
+SubstTemplateTypeParmType::SubstTemplateTypeParmType(QualType Replacement,
+ Decl *ReplacedDecl,
+ unsigned Index)
+ : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(),
+ Replacement->getDependence()),
+ ReplacedDecl(ReplacedDecl) {
+ SubstTemplateTypeParmTypeBits.Index = Index;
+ assert(ReplacedDecl != nullptr);
+ assert(getReplacedParameter() != nullptr);
+}
+
+const TemplateTypeParmDecl *
+SubstTemplateTypeParmType::getReplacedParameter() const {
+ return ::getReplacedParameter(getReplacedDecl(), getIndex());
+}
+
SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Param, QualType Canon,
+ QualType Canon, Decl *ReplacedDecl, unsigned Index,
const TemplateArgument &ArgPack)
: Type(SubstTemplateTypeParmPack, Canon,
TypeDependence::DependentInstantiation |
TypeDependence::UnexpandedPack),
- Replaced(Param), Arguments(ArgPack.pack_begin()) {
+ Arguments(ArgPack.pack_begin()), ReplacedDecl(ReplacedDecl) {
+ SubstTemplateTypeParmPackTypeBits.Index = Index;
SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+ assert(ReplacedDecl != nullptr);
+ assert(getReplacedParameter() != nullptr);
+}
+
+const TemplateTypeParmDecl *
+SubstTemplateTypeParmPackType::getReplacedParameter() const {
+ return ::getReplacedParameter(getReplacedDecl(), getIndex());
+}
+
+IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const {
+ return getReplacedParameter()->getIdentifier();
}
TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
@@ -3664,13 +3755,15 @@
}
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getArgumentPack());
+ Profile(ID, getReplacedDecl(), getIndex(), getArgumentPack());
}
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
+ const Decl *ReplacedDecl,
+ unsigned Index,
const TemplateArgument &ArgPack) {
- ID.AddPointer(Replaced);
+ ID.AddPointer(ReplacedDecl);
+ ID.AddInteger(Index);
ID.AddInteger(ArgPack.pack_size());
for (const auto &P : ArgPack.pack_elements())
ID.AddPointer(P.getAsType().getAsOpaquePtr());
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1570,6 +1570,18 @@
dumpDeclRef(T->getDecl());
}
+void TextNodeDumper::VisitSubstTemplateTypeParmType(
+ const SubstTemplateTypeParmType *T) {
+ dumpDeclRef(T->getReplacedDecl());
+ VisitTemplateTypeParmDecl(T->getReplacedParameter());
+}
+
+void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
+ const SubstTemplateTypeParmPackType *T) {
+ dumpDeclRef(T->getReplacedDecl());
+ VisitTemplateTypeParmDecl(T->getReplacedParameter());
+}
+
void TextNodeDumper::VisitAutoType(const AutoType *T) {
if (T->isDecltypeAuto())
OS << " decltype(auto)";
Index: clang/lib/AST/ODRHash.cpp
===================================================================
--- clang/lib/AST/ODRHash.cpp
+++ clang/lib/AST/ODRHash.cpp
@@ -671,7 +671,7 @@
}
}
- void AddDecl(Decl *D) {
+ void AddDecl(const Decl *D) {
Hash.AddBoolean(D);
if (D) {
Hash.AddDecl(D);
@@ -995,13 +995,13 @@
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
- AddType(T->getReplacedParameter());
+ AddDecl(T->getReplacedDecl());
Hash.AddTemplateArgument(T->getArgumentPack());
VisitType(T);
}
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- AddType(T->getReplacedParameter());
+ AddDecl(T->getReplacedDecl());
AddQualType(T->getReplacementType());
VisitType(T);
}
Index: clang/lib/AST/JSONNodeDumper.cpp
===================================================================
--- clang/lib/AST/JSONNodeDumper.cpp
+++ clang/lib/AST/JSONNodeDumper.cpp
@@ -683,6 +683,16 @@
JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));
}
+void JSONNodeDumper::VisitSubstTemplateTypeParmType(
+ const SubstTemplateTypeParmType *STTPT) {
+ JOS.attribute("index", STTPT->getIndex());
+}
+
+void JSONNodeDumper::VisitSubstTemplateTypeParmPackType(
+ const SubstTemplateTypeParmPackType *T) {
+ JOS.attribute("index", T->getIndex());
+}
+
void JSONNodeDumper::VisitAutoType(const AutoType *AT) {
JOS.attribute("undeduced", !AT->isDeduced());
switch (AT->getKeyword()) {
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===================================================================
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1055,22 +1055,24 @@
case Type::SubstTemplateTypeParm: {
const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
- if (!IsStructurallyEquivalent(Context,
- QualType(Subst1->getReplacedParameter(), 0),
- QualType(Subst2->getReplacedParameter(), 0)))
- return false;
if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(),
Subst2->getReplacementType()))
return false;
+ if (!IsStructurallyEquivalent(Context, Subst1->getReplacedDecl(),
+ Subst2->getReplacedDecl()))
+ return false;
+ if (Subst1->getIndex() != Subst2->getIndex())
+ return false;
break;
}
case Type::SubstTemplateTypeParmPack: {
const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
- if (!IsStructurallyEquivalent(Context,
- QualType(Subst1->getReplacedParameter(), 0),
- QualType(Subst2->getReplacedParameter(), 0)))
+ if (!IsStructurallyEquivalent(Context, Subst1->getReplacedDecl(),
+ Subst2->getReplacedDecl()))
+ return false;
+ if (Subst1->getIndex() != Subst2->getIndex())
return false;
if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(),
Subst2->getArgumentPack()))
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -1520,8 +1520,7 @@
ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *T) {
- Expected<const TemplateTypeParmType *> ReplacedOrErr =
- import(T->getReplacedParameter());
+ Expected<Decl *> ReplacedOrErr = import(T->getReplacedDecl());
if (!ReplacedOrErr)
return ReplacedOrErr.takeError();
@@ -1530,13 +1529,13 @@
return ToReplacementTypeOrErr.takeError();
return Importer.getToContext().getSubstTemplateTypeParmType(
- *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType());
+ ToReplacementTypeOrErr->getCanonicalType(), *ReplacedOrErr,
+ T->getIndex());
}
ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
const SubstTemplateTypeParmPackType *T) {
- Expected<const TemplateTypeParmType *> ReplacedOrErr =
- import(T->getReplacedParameter());
+ Expected<Decl *> ReplacedOrErr = import(T->getReplacedDecl());
if (!ReplacedOrErr)
return ReplacedOrErr.takeError();
@@ -1545,7 +1544,7 @@
return ToArgumentPack.takeError();
return Importer.getToContext().getSubstTemplateTypeParmPackType(
- *ReplacedOrErr, *ToArgumentPack);
+ *ReplacedOrErr, T->getIndex(), *ToArgumentPack);
}
ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
@@ -3746,6 +3745,10 @@
}
}
+ // If it is a template, import all related things.
+ if (Error Err = ImportTemplateInformation(D, ToFunction))
+ return std::move(Err);
+
if (D->doesThisDeclarationHaveABody()) {
Error Err = ImportFunctionDeclBody(D, ToFunction);
@@ -3767,10 +3770,6 @@
// FIXME: Other bits to merge?
- // If it is a template, import all related things.
- if (Error Err = ImportTemplateInformation(D, ToFunction))
- return std::move(Err);
-
addDeclToContexts(D, ToFunction);
if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
@@ -5990,6 +5989,30 @@
D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
+ if (auto P = D->getInstantiatedFrom()) {
+ if (auto *CTD = P.dyn_cast<ClassTemplateDecl *>()) {
+ if (auto CTDorErr = import(CTD))
+ D2->setInstantiationOf(*CTDorErr);
+ } else {
+ auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl *>(P);
+ auto CTPSDOrErr = import(CTPSD);
+ if (!CTPSDOrErr)
+ return CTPSDOrErr.takeError();
+ const TemplateArgumentList &DArgs = D->getTemplateInstantiationArgs();
+ SmallVector<TemplateArgument, 2> D2ArgsVec(DArgs.size());
+ for (unsigned I = 0; I < DArgs.size(); ++I) {
+ const TemplateArgument &DArg = DArgs[I];
+ if (auto ArgOrErr = import(DArg))
+ D2ArgsVec[I] = *ArgOrErr;
+ else
+ return ArgOrErr.takeError();
+ }
+ D2->setInstantiationOf(
+ *CTPSDOrErr,
+ TemplateArgumentList::CreateCopy(Importer.getToContext(), D2ArgsVec));
+ }
+ }
+
if (D->isCompleteDefinition())
if (Error Err = ImportDefinition(D, D2))
return std::move(Err);
@@ -6153,15 +6176,6 @@
}
}
} else {
- // Import the type.
- QualType T;
- if (Error Err = importInto(T, D->getType()))
- return std::move(Err);
-
- auto TInfoOrErr = import(D->getTypeSourceInfo());
- if (!TInfoOrErr)
- return TInfoOrErr.takeError();
-
TemplateArgumentListInfo ToTAInfo;
if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
@@ -6186,7 +6200,7 @@
PartVarSpecDecl *ToPartial;
if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
*BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
- VarTemplate, T, *TInfoOrErr,
+ VarTemplate, QualType(), nullptr,
D->getStorageClass(), TemplateArgs, ArgInfos))
return ToPartial;
@@ -6207,11 +6221,21 @@
} else { // Full specialization
if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
*BeginLocOrErr, *IdLocOrErr, VarTemplate,
- T, *TInfoOrErr,
- D->getStorageClass(), TemplateArgs))
+ QualType(), nullptr, D->getStorageClass(),
+ TemplateArgs))
return D2;
}
+ QualType T;
+ if (Error Err = importInto(T, D->getType()))
+ return std::move(Err);
+ D2->setType(T);
+
+ auto TInfoOrErr = import(D->getTypeSourceInfo());
+ if (!TInfoOrErr)
+ return TInfoOrErr.takeError();
+ D2->setTypeSourceInfo(*TInfoOrErr);
+
if (D->getPointOfInstantiation().isValid()) {
if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation()))
D2->setPointOfInstantiation(*POIOrErr);
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -4749,21 +4749,21 @@
}
/// Retrieve a substitution-result type.
-QualType
-ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
- QualType Replacement) const {
+QualType ASTContext::getSubstTemplateTypeParmType(QualType Replacement,
+ Decl *ReplacedDecl,
+ unsigned Index) const {
assert(Replacement.isCanonical()
&& "replacement types must always be canonical");
llvm::FoldingSetNodeID ID;
- SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
+ SubstTemplateTypeParmType::Profile(ID, Replacement, ReplacedDecl, Index);
void *InsertPos = nullptr;
- SubstTemplateTypeParmType *SubstParm
- = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+ SubstTemplateTypeParmType *SubstParm =
+ SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
if (!SubstParm) {
SubstParm = new (*this, TypeAlignment)
- SubstTemplateTypeParmType(Parm, Replacement);
+ SubstTemplateTypeParmType(Replacement, ReplacedDecl, Index);
Types.push_back(SubstParm);
SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
}
@@ -4772,34 +4772,32 @@
}
/// Retrieve a
-QualType ASTContext::getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Parm,
- const TemplateArgument &ArgPack) {
+QualType
+ASTContext::getSubstTemplateTypeParmPackType(Decl *ReplacedDecl, unsigned Index,
+ const TemplateArgument &ArgPack) {
#ifndef NDEBUG
for (const auto &P : ArgPack.pack_elements()) {
- assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type");
+ assert(P.getKind() == TemplateArgument::Type && "Pack contains a non-type");
assert(P.getAsType().isCanonical() && "Pack contains non-canonical type");
}
#endif
llvm::FoldingSetNodeID ID;
- SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
+ SubstTemplateTypeParmPackType::Profile(ID, ReplacedDecl, Index, ArgPack);
void *InsertPos = nullptr;
- if (SubstTemplateTypeParmPackType *SubstParm
- = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
+ if (SubstTemplateTypeParmPackType *SubstParm =
+ SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(SubstParm, 0);
QualType Canon;
- if (!Parm->isCanonicalUnqualified()) {
- Canon = getCanonicalType(QualType(Parm, 0));
- Canon = getSubstTemplateTypeParmPackType(cast<TemplateTypeParmType>(Canon),
- ArgPack);
+ if (!ReplacedDecl->isCanonicalDecl()) {
+ Canon = getSubstTemplateTypeParmPackType(ReplacedDecl->getCanonicalDecl(),
+ Index, ArgPack);
SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);
}
- auto *SubstParm
- = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon,
- ArgPack);
+ auto *SubstParm = new (*this, TypeAlignment)
+ SubstTemplateTypeParmPackType(Canon, ReplacedDecl, Index, ArgPack);
Types.push_back(SubstParm);
SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos);
return QualType(SubstParm, 0);
@@ -12819,12 +12817,14 @@
case Type::SubstTemplateTypeParm: {
const auto *SX = cast<SubstTemplateTypeParmType>(X),
*SY = cast<SubstTemplateTypeParmType>(Y);
- const TemplateTypeParmType *PX = SX->getReplacedParameter();
- if (PX != SY->getReplacedParameter())
+ unsigned Index = SX->getIndex();
+ if (Index != SY->getIndex())
return QualType();
-
- return Ctx.getSubstTemplateTypeParmType(PX,
- Ctx.getQualifiedType(Underlying));
+ Decl *CD = ::getCommonDecl(SX->getReplacedDecl(), SY->getReplacedDecl());
+ if (!CD)
+ return QualType();
+ return Ctx.getSubstTemplateTypeParmType(Ctx.getQualifiedType(Underlying),
+ CD, Index);
}
case Type::ObjCTypeParam:
// FIXME: Try to merge these.
Index: clang/include/clang/Sema/Template.h
===================================================================
--- clang/include/clang/Sema/Template.h
+++ clang/include/clang/Sema/Template.h
@@ -74,13 +74,20 @@
/// template argument list (17) at depth 1.
class MultiLevelTemplateArgumentList {
/// The template argument list at a certain template depth
+
using ArgList = ArrayRef<TemplateArgument>;
- using ArgListsIterator = SmallVector<ArgList, 4>::iterator;
- using ConstArgListsIterator = SmallVector<ArgList, 4>::const_iterator;
+ struct ArgumentListLevel {
+ Decl *ReplacedDecl;
+ ArgList Args;
+ };
+ using ContainerType = SmallVector<ArgumentListLevel, 4>;
+
+ using ArgListsIterator = ContainerType::iterator;
+ using ConstArgListsIterator = ContainerType::const_iterator;
/// The template argument lists, stored from the innermost template
/// argument list (first) to the outermost template argument list (last).
- SmallVector<ArgList, 4> TemplateArgumentLists;
+ ContainerType TemplateArgumentLists;
/// The number of outer levels of template arguments that are not
/// being substituted.
@@ -94,9 +101,8 @@
MultiLevelTemplateArgumentList() = default;
/// Construct a single-level template argument list.
- explicit
- MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
- addOuterTemplateArguments(&TemplateArgs);
+ explicit MultiLevelTemplateArgumentList(Decl *D, ArgList Args) {
+ addOuterTemplateArguments(D, Args);
}
void setKind(TemplateSubstitutionKind K) { Kind = K; }
@@ -126,7 +132,7 @@
// Determine the number of substituted args at 'Depth'.
unsigned getNumSubsitutedArgs(unsigned Depth) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
- return TemplateArgumentLists[getNumLevels() - Depth - 1].size();
+ return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size();
}
unsigned getNumRetainedOuterLevels() const {
@@ -146,8 +152,14 @@
/// Retrieve the template argument at a given depth and index.
const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
- return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
+ assert(Index <
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
+ return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index];
+ }
+
+ Decl *getReplacedDecl(unsigned Depth) const {
+ assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
+ return TemplateArgumentLists[getNumLevels() - Depth - 1].ReplacedDecl;
}
/// Determine whether there is a non-NULL template argument at the
@@ -160,15 +172,16 @@
if (Depth < NumRetainedOuterLevels)
return false;
- if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
+ if (Index >=
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size())
return false;
return !(*this)(Depth, Index).isNull();
}
bool isAnyArgInstantiationDependent() const {
- for (ArgList List : TemplateArgumentLists)
- for (const TemplateArgument &TA : List)
+ for (ArgumentListLevel ListLevel : TemplateArgumentLists)
+ for (const TemplateArgument &TA : ListLevel.Args)
if (TA.isInstantiationDependent())
return true;
return false;
@@ -178,25 +191,34 @@
void setArgument(unsigned Depth, unsigned Index,
TemplateArgument Arg) {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
- const_cast<TemplateArgument&>(
- TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
- = Arg;
+ assert(Index <
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
+ const_cast<TemplateArgument &>(
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg;
}
- /// Add a new outermost level to the multi-level template argument
+ /// Add a new outmost level to the multi-level template argument
/// list.
- void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
- addOuterTemplateArguments(ArgList(TemplateArgs->data(),
- TemplateArgs->size()));
+ void addOuterTemplateArguments(Decl *ReplacedDecl, ArgList Args) {
+ assert(!NumRetainedOuterLevels &&
+ "substituted args outside retained args?");
+ assert(getKind() == TemplateSubstitutionKind::Specialization);
+ assert(ReplacedDecl != nullptr || Args.size() == 0);
+ TemplateArgumentLists.push_back(
+ {ReplacedDecl ? ReplacedDecl->getCanonicalDecl() : nullptr, Args});
}
- /// Add a new outmost level to the multi-level template argument
- /// list.
void addOuterTemplateArguments(ArgList Args) {
assert(!NumRetainedOuterLevels &&
"substituted args outside retained args?");
- TemplateArgumentLists.push_back(Args);
+ assert(getKind() == TemplateSubstitutionKind::Rewrite);
+ TemplateArgumentLists.push_back({nullptr, Args});
+ }
+
+ void addOuterTemplateArguments(llvm::NoneType) {
+ assert(!NumRetainedOuterLevels &&
+ "substituted args outside retained args?");
+ TemplateArgumentLists.push_back({});
}
/// Replaces the current 'innermost' level with the provided argument list.
@@ -204,7 +226,7 @@
/// list from the AST, but then add the deduced innermost list.
void replaceInnermostTemplateArguments(ArgList Args) {
assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?");
- TemplateArgumentLists[0] = Args;
+ TemplateArgumentLists[0].Args = Args;
}
/// Add an outermost level that we are not substituting. We have no
@@ -219,11 +241,11 @@
/// Retrieve the innermost template argument list.
const ArgList &getInnermost() const {
- return TemplateArgumentLists.front();
+ return TemplateArgumentLists.front().Args;
}
/// Retrieve the outermost template argument list.
const ArgList &getOutermost() const {
- return TemplateArgumentLists.back();
+ return TemplateArgumentLists.back().Args;
}
ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
ConstArgListsIterator begin() const {
Index: clang/include/clang/AST/TypeProperties.td
===================================================================
--- clang/include/clang/AST/TypeProperties.td
+++ clang/include/clang/AST/TypeProperties.td
@@ -728,18 +728,20 @@
}
let Class = SubstTemplateTypeParmType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
- }
def : Property<"replacementType", QualType> {
let Read = [{ node->getReplacementType() }];
}
+ def : Property<"replacedDecl", DeclRef> {
+ let Read = [{ node->getReplacedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
+ }
+ // The call to getCanonicalType here existed in ASTReader.cpp, too.
def : Creator<[{
- // The call to getCanonicalType here existed in ASTReader.cpp, too.
return ctx.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(replacedParameter),
- ctx.getCanonicalType(replacementType));
+ ctx.getCanonicalType(replacementType), replacedDecl, Index);
}]>;
}
@@ -758,8 +760,11 @@
}
let Class = SubstTemplateTypeParmPackType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
+ def : Property<"replacedDecl", DeclRef> {
+ let Read = [{ node->getReplacedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
}
def : Property<"replacementPack", TemplateArgument> {
let Read = [{ node->getArgumentPack() }];
@@ -767,8 +772,7 @@
def : Creator<[{
return ctx.getSubstTemplateTypeParmPackType(
- cast<TemplateTypeParmType>(replacedParameter),
- replacementPack);
+ replacedDecl, Index, replacementPack);
}]>;
}
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1793,19 +1793,28 @@
unsigned NumArgs;
};
+ class SubstTemplateTypeParmTypeBitfields {
+ friend class SubstTemplateTypeParmType;
+
+ unsigned : NumTypeBits;
+
+ // The index of the template parameter this substitution represents.
+ unsigned Index;
+ };
+
class SubstTemplateTypeParmPackTypeBitfields {
friend class SubstTemplateTypeParmPackType;
unsigned : NumTypeBits;
+ // The index of the template parameter this substitution represents.
+ unsigned Index : 16;
+
/// The number of template arguments in \c Arguments, which is
/// expected to be able to hold at least 1024 according to [implimits].
/// However as this limit is somewhat easy to hit with template
/// metaprogramming we'd prefer to keep it as large as possible.
- /// At the moment it has been left as a non-bitfield since this type
- /// safely fits in 64 bits as an unsigned, so there is no reason to
- /// introduce the performance impact of a bitfield.
- unsigned NumArgs;
+ unsigned NumArgs : 16;
};
class TemplateSpecializationTypeBitfields {
@@ -1874,6 +1883,7 @@
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
+ SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
@@ -4974,37 +4984,35 @@
class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- // The original type parameter.
- const TemplateTypeParmType *Replaced;
+ Decl *ReplacedDecl;
- SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
- Replaced(Param) {}
+ SubstTemplateTypeParmType(QualType Replacement, Decl *ReplacedDecl,
+ unsigned Index);
public:
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
/// Gets the type that was substituted for the template
/// parameter.
- QualType getReplacementType() const {
- return getCanonicalTypeInternal();
- }
+ QualType getReplacementType() const { return getCanonicalTypeInternal(); }
+
+ /// Gets the templated entity that was substituted.
+ Decl *getReplacedDecl() const { return ReplacedDecl; }
+
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; }
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getReplacementType());
+ Profile(ID, getReplacementType(), getReplacedDecl(), getIndex());
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- QualType Replacement) {
- ID.AddPointer(Replaced);
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
+ const Decl *ReplacedDecl, unsigned Index) {
+ ID.AddPointer(ReplacedDecl);
ID.AddPointer(Replacement.getAsOpaquePtr());
+ ID.AddInteger(Index);
}
static bool classof(const Type *T) {
@@ -5027,24 +5035,25 @@
class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- /// The original type parameter.
- const TemplateTypeParmType *Replaced;
-
/// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
- QualType Canon,
+ Decl *ReplacedDecl;
+
+ SubstTemplateTypeParmPackType(QualType Canon, Decl *ReplacedDecl,
+ unsigned Index,
const TemplateArgument &ArgPack);
public:
- IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
+ IdentifierInfo *getIdentifier() const;
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
+ /// Gets the templated entity that was substituted.
+ Decl *getReplacedDecl() const { return ReplacedDecl; }
+
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
unsigned getNumArgs() const {
return SubstTemplateTypeParmPackTypeBits.NumArgs;
@@ -5056,9 +5065,8 @@
TemplateArgument getArgumentPack() const;
void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- const TemplateArgument &ArgPack);
+ static void Profile(llvm::FoldingSetNodeID &ID, const Decl *ReplacedDecl,
+ unsigned Index, const TemplateArgument &ArgPack);
static bool classof(const Type *T) {
return T->getTypeClass() == SubstTemplateTypeParmPack;
Index: clang/include/clang/AST/TextNodeDumper.h
===================================================================
--- clang/include/clang/AST/TextNodeDumper.h
+++ clang/include/clang/AST/TextNodeDumper.h
@@ -317,6 +317,9 @@
void VisitUnaryTransformType(const UnaryTransformType *T);
void VisitTagType(const TagType *T);
void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *T);
void VisitDeducedTemplateSpecializationType(
const DeducedTemplateSpecializationType *T);
Index: clang/include/clang/AST/JSONNodeDumper.h
===================================================================
--- clang/include/clang/AST/JSONNodeDumper.h
+++ clang/include/clang/AST/JSONNodeDumper.h
@@ -220,6 +220,9 @@
void VisitUnaryTransformType(const UnaryTransformType *UTT);
void VisitTagType(const TagType *TT);
void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *AT);
void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
Index: clang/include/clang/AST/ASTNodeTraverser.h
===================================================================
--- clang/include/clang/AST/ASTNodeTraverser.h
+++ clang/include/clang/AST/ASTNodeTraverser.h
@@ -389,12 +389,9 @@
void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
Visit(T->getWrappedType());
}
- void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- Visit(T->getReplacedParameter());
- }
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
- Visit(T->getReplacedParameter());
Visit(T->getArgumentPack());
}
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1616,10 +1616,10 @@
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
QualType Wrapped);
- QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
- QualType Replacement) const;
- QualType getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Replaced,
+ QualType getSubstTemplateTypeParmType(QualType Replacement,
+ Decl *ReplacedDecl,
+ unsigned Index) const;
+ QualType getSubstTemplateTypeParmPackType(Decl *ReplacedDecl, unsigned Index,
const TemplateArgument &ArgPack);
QualType
Index: clang-tools-extra/clangd/AST.cpp
===================================================================
--- clang-tools-extra/clangd/AST.cpp
+++ clang-tools-extra/clangd/AST.cpp
@@ -727,8 +727,8 @@
if (const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
const auto *ReplacedParameter = SubstType->getReplacedParameter();
if (ReplacedParameter->isParameterPack()) {
- return dyn_cast<TemplateTypeParmType>(
- ReplacedParameter->getCanonicalTypeUnqualified()->getTypePtr());
+ return ReplacedParameter->getTypeForDecl()
+ ->castAs<TemplateTypeParmType>();
}
}
return nullptr;
Index: clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
===================================================================
--- clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -191,12 +191,12 @@
getSubstitutedType(VarType, Context)) {
if (const SubstTemplateTypeParmType *InitializerTmplType =
getSubstitutedType(InitializerType, Context)) {
- return VarTmplType->getReplacedParameter()
- ->desugar()
- .getCanonicalType() !=
- InitializerTmplType->getReplacedParameter()
- ->desugar()
- .getCanonicalType();
+ const TemplateTypeParmDecl *VarTTP = VarTmplType->getReplacedParameter();
+ const TemplateTypeParmDecl *InitTTP =
+ InitializerTmplType->getReplacedParameter();
+ return (VarTTP->getDepth() != InitTTP->getDepth() ||
+ VarTTP->getIndex() != InitTTP->getIndex() ||
+ VarTTP->isParameterPack() != InitTTP->isParameterPack());
}
}
return false;
Index: clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
+++ clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
@@ -52,7 +52,7 @@
diag(BadThrow->getSubExpr()->getBeginLoc(),
"type %0 is a template instantiation of %1", DiagnosticIDs::Note)
<< BadThrow->getSubExpr()->getType()
- << Template->getReplacedParameter()->getDecl();
+ << Template->getReplacedParameter();
if (const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl"))
diag(TypeDecl->getBeginLoc(), "type defined here", DiagnosticIDs::Note);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits