[clang] [clang-tools-extra] Revert "[Clang] Add a builtin that deduplicate types into a pack (#106730)" (PR #154606)
Kazu Hirata via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 20 13:26:53 PDT 2025
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/154606
This reverts commits 85043c1c146fd5658ad4c5b5138e58994333e645 and
65de318d186c815f43b892aa20b98c50f22ab6fe.
The first commit above triggers the following warnings:
clang/lib/Sema/SemaTemplateVariadic.cpp:1069:22: error: variable
'TST' set but not used [-Werror,-Wunused-but-set-variable]
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4148:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
4148 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4852:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
4852 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:5153:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
5153 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
>From b2738f59a2c98c9e8b85447a8dc84f3ffc2c5815 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 20 Aug 2025 13:03:17 -0700
Subject: [PATCH] Revert "[Clang] Add a builtin that deduplicate types into a
pack (#106730)"
This reverts commits 85043c1c146fd5658ad4c5b5138e58994333e645 and
65de318d186c815f43b892aa20b98c50f22ab6fe.
The first commit above triggers the following warnings:
clang/lib/Sema/SemaTemplateVariadic.cpp:1069:22: error: variable
'TST' set but not used [-Werror,-Wunused-but-set-variable]
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4148:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
4148 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4852:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
4852 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:5153:11:
error: enumeration value 'SubstBuiltinTemplatePack' not handled in
switch [-Werror,-Wswitch]
5153 | switch (qual_type->getTypeClass()) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
---
.../clangd/unittests/FindTargetTests.cpp | 6 -
clang/docs/LanguageExtensions.rst | 31 --
clang/docs/ReleaseNotes.rst | 16 -
clang/include/clang/AST/ASTContext.h | 3 -
clang/include/clang/AST/DeclTemplate.h | 3 -
clang/include/clang/AST/RecursiveASTVisitor.h | 30 +-
clang/include/clang/AST/Type.h | 80 +----
clang/include/clang/AST/TypeLoc.h | 22 +-
clang/include/clang/AST/TypeProperties.td | 19 +-
clang/include/clang/Basic/BuiltinTemplates.td | 4 -
.../clang/Basic/DiagnosticSemaKinds.td | 7 -
clang/include/clang/Basic/TypeNodes.td | 4 +-
clang/include/clang/Sema/Sema.h | 18 +-
clang/include/clang/Sema/SemaInternal.h | 11 +-
.../clang/Serialization/TypeBitCodes.def | 1 -
clang/lib/AST/ASTContext.cpp | 31 +-
clang/lib/AST/ASTImporter.cpp | 8 -
clang/lib/AST/ASTStructuralEquivalence.cpp | 8 -
clang/lib/AST/DeclTemplate.cpp | 13 +-
clang/lib/AST/ItaniumMangle.cpp | 15 -
clang/lib/AST/MicrosoftMangle.cpp | 5 -
clang/lib/AST/Type.cpp | 87 ++---
clang/lib/AST/TypePrinter.cpp | 10 -
clang/lib/Parse/ParseTemplate.cpp | 2 -
clang/lib/Sema/SemaConcept.cpp | 13 +-
clang/lib/Sema/SemaDeclCXX.cpp | 3 +-
clang/lib/Sema/SemaTemplate.cpp | 57 ----
clang/lib/Sema/SemaTemplateDeduction.cpp | 18 +-
clang/lib/Sema/SemaTemplateInstantiate.cpp | 177 ++--------
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 52 +--
clang/lib/Sema/SemaTemplateVariadic.cpp | 122 +------
clang/lib/Sema/TreeTransform.h | 319 ++++++------------
clang/lib/Serialization/ASTReader.cpp | 5 -
clang/lib/Serialization/ASTWriter.cpp | 6 -
.../test/Import/builtin-template/Inputs/S.cpp | 10 -
clang/test/Import/builtin-template/test.cpp | 12 +-
clang/test/PCH/dedup_types.cpp | 20 --
clang/test/SemaCXX/pr100095.cpp | 1 +
.../test/SemaTemplate/dedup-types-builtin.cpp | 226 -------------
clang/tools/libclang/CIndex.cpp | 1 -
40 files changed, 237 insertions(+), 1239 deletions(-)
delete mode 100644 clang/test/PCH/dedup_types.cpp
delete mode 100644 clang/test/SemaTemplate/dedup-types-builtin.cpp
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index f369e1b0341e8..20fd23ed4fcdc 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -731,12 +731,6 @@ TEST_F(TargetDeclTest, BuiltinTemplates) {
using type_pack_element = [[__type_pack_element]]<N, Pack...>;
)cpp";
EXPECT_DECLS("TemplateSpecializationTypeLoc", );
-
- Code = R"cpp(
- template <template <class...> class Templ, class... Types>
- using dedup_types = Templ<[[__builtin_dedup_pack]]<Types...>...>;
- )cpp";
- EXPECT_DECLS("TemplateSpecializationTypeLoc", );
}
TEST_F(TargetDeclTest, MemberOfTemplate) {
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 1b749ead355c7..3f7b7bb270325 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1829,37 +1829,6 @@ __make_integer_seq
This alias returns ``IntSeq`` instantiated with ``IntSeqT = T``and ``Ints`` being the pack ``0, ..., N - 1``.
-__builtin_dedup_pack
---------------------
-
-.. code-block:: c++
-
- template <class... Ts>
- using __builtin_dedup_pack = ...;
-
-This alias takes a template parameter pack ``Ts`` and produces a new unexpanded pack containing the unique types
-from ``Ts``, with the order of the first occurrence of each type preserved.
-It is useful in template metaprogramming to normalize type lists.
-
-The resulting pack can be expanded in contexts like template argument lists or base specifiers.
-
-**Example of Use**:
-
-.. code-block:: c++
-
- template <typename...> struct TypeList;
-
- // The resulting type is TypeList<int, double, char>
- template <typename ...ExtraTypes>
- using MyTypeList = TypeList<__builtin_dedup_pack<int, double, int, char, double, ExtraTypes...>...>;
-
-**Limitations**:
-
-* This builtin can only be used inside a template.
-* The resulting pack is currently only supported for expansion in template argument lists and base specifiers.
-* This builtin cannot be assigned to a template template parameter.
-
-
Type Trait Primitives
=====================
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d577192d2791f..338627904e7f9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -148,22 +148,6 @@ Non-comprehensive list of changes in this release
correct method to check for these features is to test for the ``__PTRAUTH__``
macro.
-- Added a new builtin, ``__builtin_dedup_pack``, to remove duplicate types from a parameter pack.
- This feature is particularly useful in template metaprogramming for normalizing type lists.
- The builtin produces a new, unexpanded parameter pack that can be used in contexts like template
- argument lists or base specifiers.
-
- .. code-block:: c++
-
- template <typename...> struct TypeList;
-
- // The resulting type is TypeList<int, double, char>
- using MyTypeList = TypeList<__builtin_dedup_pack<int, double, int, char, double>...>;
-
- Currently, the use of ``__builtin_dedup_pack`` is limited to template arguments and base
- specifiers, it also must be used within a template context.
-
-
New Compiler Flags
------------------
- New option ``-fno-sanitize-annotate-debug-info-traps`` added to disable emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``).
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 07f4935e06555..7c2566a09665d 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -230,8 +230,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
SubstTemplateTypeParmTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
SubstTemplateTypeParmPackTypes;
- mutable llvm::FoldingSet<SubstBuiltinTemplatePackType>
- SubstBuiltinTemplatePackTypes;
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes;
mutable llvm::FoldingSet<ParenType> ParenTypes{GeneralTypesLog2InitSize};
@@ -1897,7 +1895,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
unsigned Index, bool Final,
const TemplateArgument &ArgPack);
- QualType getSubstBuiltinTemplatePack(const TemplateArgument &ArgPack);
QualType
getTemplateTypeParmType(unsigned Depth, unsigned Index,
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index bba72365089f9..f298ed8b2f640 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1796,10 +1796,7 @@ class BuiltinTemplateDecl : public TemplateDecl {
}
BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
-
- bool isPackProducingBuiltinTemplate() const;
};
-bool isPackProducingBuiltinTemplateName(TemplateName N);
/// Provides information about an explicit instantiation of a variable or class
/// template.
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 02581c8e73299..248b89200eace 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -492,8 +492,6 @@ template <typename Derived> class RecursiveASTVisitor {
bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
unsigned Count);
bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
- bool TraverseSubstPackTypeHelper(SubstPackType *T);
- bool TraverseSubstPackTypeLocHelper(SubstPackTypeLoc TL);
bool TraverseRecordHelper(RecordDecl *D);
bool TraverseCXXRecordHelper(CXXRecordDecl *D);
bool TraverseDeclaratorHelper(DeclaratorDecl *D);
@@ -1140,10 +1138,9 @@ DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
TRY_TO(TraverseType(T->getReplacementType()));
})
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType,
- { TRY_TO(TraverseSubstPackTypeHelper(T)); })
-DEF_TRAVERSE_TYPE(SubstBuiltinTemplatePackType,
- { TRY_TO(TraverseSubstPackTypeHelper(T)); })
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
+ TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
+})
DEF_TRAVERSE_TYPE(AttributedType,
{ TRY_TO(TraverseType(T->getModifiedType())); })
@@ -1484,26 +1481,9 @@ DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeLocHelper(
- SubstPackTypeLoc TL) {
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {
TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeHelper(
- SubstPackType *T) {
- TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
- return true;
-}
-
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType,
- { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
-
-DEF_TRAVERSE_TYPELOC(SubstBuiltinTemplatePackType,
- { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
+})
DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index adf5cb0462154..3c32f7c82a3c1 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2210,24 +2210,20 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned PackIndex : 15;
};
- class SubstPackTypeBitfields {
- friend class SubstPackType;
+ class SubstTemplateTypeParmPackTypeBitfields {
friend class SubstTemplateTypeParmPackType;
LLVM_PREFERRED_TYPE(TypeBitfields)
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.
unsigned NumArgs : 16;
-
- // The index of the template parameter this substitution represents.
- // Only used by SubstTemplateTypeParmPackType. We keep it in the same
- // class to avoid dealing with complexities of bitfields that go over
- // the size of `unsigned`.
- unsigned SubstTemplTypeParmPackIndex : 16;
};
class TemplateSpecializationTypeBitfields {
@@ -2344,7 +2340,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
VectorTypeBitfields VectorTypeBits;
TemplateTypeParmTypeBitfields TemplateTypeParmTypeBits;
SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
- SubstPackTypeBitfields SubstPackTypeBits;
+ SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
DependentTemplateSpecializationTypeBits;
@@ -6996,56 +6992,6 @@ class SubstTemplateTypeParmType final
}
};
-/// Represents the result of substituting a set of types as a template argument
-/// that needs to be expanded later.
-///
-/// These types are always dependent and produced depending on the situations:
-/// - SubstTemplateTypeParmPack is an expansion that had to be delayed,
-/// - SubstBuiltinTemplatePackType is an expansion from a builtin.
-class SubstPackType : public Type, public llvm::FoldingSetNode {
- friend class ASTContext;
-
- /// A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
-
-protected:
- SubstPackType(TypeClass Derived, QualType Canon,
- const TemplateArgument &ArgPack);
-
-public:
- unsigned getNumArgs() const { return SubstPackTypeBits.NumArgs; }
-
- TemplateArgument getArgumentPack() const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateArgument &ArgPack);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstTemplateTypeParmPack ||
- T->getTypeClass() == SubstBuiltinTemplatePack;
- }
-};
-
-/// Represents the result of substituting a builtin template as a pack.
-class SubstBuiltinTemplatePackType : public SubstPackType {
- friend class ASTContext;
-
- SubstBuiltinTemplatePackType(QualType Canon, const TemplateArgument &ArgPack);
-
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- /// Mark that we reuse the Profile. We do not introduce new fields.
- using SubstPackType::Profile;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstBuiltinTemplatePack;
- }
-};
-
/// Represents the result of substituting a set of types for a template
/// type parameter pack.
///
@@ -7058,7 +7004,7 @@ class SubstBuiltinTemplatePackType : public SubstPackType {
/// that pack expansion (e.g., when all template parameters have corresponding
/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
/// at the current pack substitution index.
-class SubstTemplateTypeParmPackType : public SubstPackType {
+class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
/// A pointer to the set of template arguments that this
@@ -7084,17 +7030,21 @@ class SubstTemplateTypeParmPackType : public SubstPackType {
/// Returns the index of the replaced parameter in the associated declaration.
/// This should match the result of `getReplacedParameter()->getIndex()`.
- unsigned getIndex() const {
- return SubstPackTypeBits.SubstTemplTypeParmPackIndex;
- }
+ unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
// This substitution will be Final, which means the substitution will be fully
// sugared: it doesn't need to be resugared later.
bool getFinal() const;
+ unsigned getNumArgs() const {
+ return SubstTemplateTypeParmPackTypeBits.NumArgs;
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ TemplateArgument getArgumentPack() const;
+
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl,
unsigned Index, bool Final,
@@ -7329,7 +7279,9 @@ class TemplateSpecializationType : public TypeWithKeyword,
TemplateSpecializationTypeBits.NumArgs};
}
- bool isSugared() const;
+ bool isSugared() const {
+ return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
+ }
QualType desugar() const {
return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 00835f1490eda..6389bdea6d122 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -989,22 +989,12 @@ class SubstTemplateTypeParmTypeLoc :
SubstTemplateTypeParmType> {
};
-/// Abstract type representing delayed type pack expansions.
-class SubstPackTypeLoc
- : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, SubstPackTypeLoc,
- SubstPackType> {};
-
-/// Wrapper for substituted template type parameters.
-class SubstTemplateTypeParmPackTypeLoc
- : public InheritingConcreteTypeLoc<SubstPackTypeLoc,
- SubstTemplateTypeParmPackTypeLoc,
- SubstTemplateTypeParmPackType> {};
-
-/// Wrapper for substituted template type parameters.
-class SubstBuiltinTemplatePackTypeLoc
- : public InheritingConcreteTypeLoc<SubstPackTypeLoc,
- SubstBuiltinTemplatePackTypeLoc,
- SubstBuiltinTemplatePackType> {};
+ /// Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmPackTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ SubstTemplateTypeParmPackTypeLoc,
+ SubstTemplateTypeParmPackType> {
+};
struct AttributedLocInfo {
const Attr *TypeAttr;
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 185a968217f97..388f6dda4a6f0 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -820,12 +820,6 @@ let Class = PackExpansionType in {
}]>;
}
-let Class = SubstPackType in {
- def : Property<"replacementPack", TemplateArgument> {
- let Read = [{ node->getArgumentPack() }];
- }
-}
-
let Class = SubstTemplateTypeParmPackType in {
def : Property<"associatedDecl", DeclRef> {
let Read = [{ node->getAssociatedDecl() }];
@@ -833,7 +827,12 @@ let Class = SubstTemplateTypeParmPackType in {
def : Property<"Index", UInt32> {
let Read = [{ node->getIndex() }];
}
- def : Property<"Final", Bool> { let Read = [{ node->getFinal() }]; }
+ def : Property<"Final", Bool> {
+ let Read = [{ node->getFinal() }];
+ }
+ def : Property<"replacementPack", TemplateArgument> {
+ let Read = [{ node->getArgumentPack() }];
+ }
def : Creator<[{
return ctx.getSubstTemplateTypeParmPackType(
@@ -841,12 +840,6 @@ let Class = SubstTemplateTypeParmPackType in {
}]>;
}
-let Class = SubstBuiltinTemplatePackType in {
- def : Creator<[{
- return ctx.getSubstBuiltinTemplatePack(replacementPack);
- }]>;
-}
-
let Class = BuiltinType in {
def : Property<"kind", BuiltinTypeKind> {
let Read = [{ node->getKind() }];
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index 504405acbdc78..5b9672b395955 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -62,7 +62,3 @@ def __builtin_common_type : CPlusPlusBuiltinTemplate<
// typename ...Operands>
def __hlsl_spirv_type : HLSLBuiltinTemplate<
[Uint32T, Uint32T, Uint32T, Class<"Operands", /*is_variadic=*/1>]>;
-
-// template <class ...Args>
-def __builtin_dedup_pack
- : CPlusPlusBuiltinTemplate<[Class<"Args", /*is_variadic=*/1>]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f40cac865ade0..24723573cc861 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6074,13 +6074,6 @@ def warn_cxx23_pack_indexing : Warning<
def err_pack_outside_template : Error<
"pack declaration outside of template">;
-def err_builtin_pack_outside_template
- : Error<"%0 cannot be used outside of template">;
-
-def err_unsupported_builtin_template_pack_expansion
- : Error<"expansions of %0 are not supported here. Only expansions in "
- "template arguments and class bases are supported">;
-
def err_fold_expression_packs_both_sides : Error<
"binary fold expression has unexpanded parameter packs in both operands">;
def err_fold_expression_empty : Error<
diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td
index c8d45dec78816..e4960ec660b90 100644
--- a/clang/include/clang/Basic/TypeNodes.td
+++ b/clang/include/clang/Basic/TypeNodes.td
@@ -97,9 +97,7 @@ def HLSLAttributedResourceType : TypeNode<Type>;
def HLSLInlineSpirvType : TypeNode<Type>;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
-def SubstPackType : TypeNode<Type, 1>;
-def SubstTemplateTypeParmPackType : TypeNode<SubstPackType>, AlwaysDependent;
-def SubstBuiltinTemplatePackType : TypeNode<SubstPackType>, AlwaysDependent;
+def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
def TemplateSpecializationType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def DeducedType : TypeNode<Type, 1>;
def AutoType : TypeNode<DeducedType>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 12112eb1ad225..89d3f61380db1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -228,9 +228,7 @@ void threadSafetyCleanup(BeforeSet *Cache);
// FIXME: No way to easily map from TemplateTypeParmTypes to
// TemplateTypeParmDecls, so we have this horrible PointerUnion.
-typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *,
- const TemplateSpecializationType *,
- const SubstBuiltinTemplatePackType *>,
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *>,
SourceLocation>
UnexpandedParameterPack;
@@ -13499,6 +13497,8 @@ class Sema final : public SemaBase {
~ArgPackSubstIndexRAII() { Self.ArgPackSubstIndex = OldSubstIndex; }
};
+ friend class ArgumentPackSubstitutionRAII;
+
void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
void popCodeSynthesisContext();
@@ -14428,15 +14428,6 @@ class Sema final : public SemaBase {
static void collectUnexpandedParameterPacks(
Expr *E, SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// Invoked when parsing a template argument.
- ///
- /// \param Arg the template argument, which may already be invalid.
- ///
- /// If it is followed by ellipsis, this function is called before
- /// `ActOnPackExpansion`.
- ParsedTemplateArgument
- ActOnTemplateTemplateArgument(const ParsedTemplateArgument &Arg);
-
/// Invoked when parsing a template argument followed by an
/// ellipsis, which creates a pack expansion.
///
@@ -14524,8 +14515,7 @@ class Sema final : public SemaBase {
bool CheckParameterPacksForExpansion(
SourceLocation EllipsisLoc, SourceRange PatternRange,
ArrayRef<UnexpandedParameterPack> Unexpanded,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- bool FailOnPackProducingTemplates, bool &ShouldExpand,
+ const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
bool &RetainExpansion, UnsignedOrNone &NumExpansions);
/// Determine the number of arguments in the given pack expansion
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 8f6041b5f00e4..f7c67c15379f1 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -71,17 +71,12 @@ inline std::pair<unsigned, unsigned> getDepthAndIndex(const NamedDecl *ND) {
}
/// Retrieve the depth and index of an unexpanded parameter pack.
-/// Returns nullopt when the unexpanded packs do not correspond to template
-/// parameters, e.g. __builtin_dedup_types.
-inline std::optional<std::pair<unsigned, unsigned>>
+inline std::pair<unsigned, unsigned>
getDepthAndIndex(UnexpandedParameterPack UPP) {
if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(UPP.first))
return std::make_pair(TTP->getDepth(), TTP->getIndex());
- if (isa<NamedDecl *>(UPP.first))
- return getDepthAndIndex(cast<NamedDecl *>(UPP.first));
- assert((isa<const TemplateSpecializationType *,
- const SubstBuiltinTemplatePackType *>(UPP.first)));
- return std::nullopt;
+
+ return getDepthAndIndex(cast<NamedDecl *>(UPP.first));
}
class TypoCorrectionConsumer : public VisibleDeclConsumer {
diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def
index bea15254922c1..8af32db4c0b39 100644
--- a/clang/include/clang/Serialization/TypeBitCodes.def
+++ b/clang/include/clang/Serialization/TypeBitCodes.def
@@ -69,6 +69,5 @@ TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58)
TYPE_BIT_CODE(HLSLAttributedResource, HLSLRESOURCE_ATTRIBUTED, 59)
TYPE_BIT_CODE(HLSLInlineSpirv, HLSL_INLINE_SPIRV, 60)
TYPE_BIT_CODE(PredefinedSugar, PREDEFINED_SUGAR, 61)
-TYPE_BIT_CODE(SubstBuiltinTemplatePack, SUBST_BUILTIN_TEMPLATE_PACK, 62)
#undef TYPE_BIT_CODE
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bbb957067c4c8..fe0b247c36831 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4306,7 +4306,6 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::DependentTemplateSpecialization:
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
- case Type::SubstBuiltinTemplatePack:
case Type::Auto:
case Type::DeducedTemplateSpecialization:
case Type::PackExpansion:
@@ -5849,6 +5848,7 @@ QualType ASTContext::getSubstTemplateTypeParmType(QualType Replacement,
return QualType(SubstParm, 0);
}
+/// Retrieve a
QualType
ASTContext::getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
unsigned Index, bool Final,
@@ -5887,34 +5887,6 @@ ASTContext::getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
return QualType(SubstParm, 0);
}
-QualType
-ASTContext::getSubstBuiltinTemplatePack(const TemplateArgument &ArgPack) {
- assert(llvm::all_of(ArgPack.pack_elements(),
- [](const auto &P) {
- return P.getKind() == TemplateArgument::Type;
- }) &&
- "Pack contains a non-type");
-
- llvm::FoldingSetNodeID ID;
- SubstBuiltinTemplatePackType::Profile(ID, ArgPack);
-
- void *InsertPos = nullptr;
- if (auto *T =
- SubstBuiltinTemplatePackTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(T, 0);
-
- QualType Canon;
- TemplateArgument CanonArgPack = getCanonicalTemplateArgument(ArgPack);
- if (!CanonArgPack.structurallyEquals(ArgPack))
- Canon = getSubstBuiltinTemplatePack(CanonArgPack);
-
- auto *PackType = new (*this, alignof(SubstBuiltinTemplatePackType))
- SubstBuiltinTemplatePackType(Canon, ArgPack);
- Types.push_back(PackType);
- SubstBuiltinTemplatePackTypes.InsertNode(PackType, InsertPos);
- return QualType(PackType, 0);
-}
-
/// Retrieve the template type parameter type for a template
/// parameter or parameter pack with the given depth, index, and (optionally)
/// name.
@@ -14072,7 +14044,6 @@ static QualType getCommonNonSugarTypeNode(const ASTContext &Ctx, const Type *X,
SUGAR_FREE_TYPE(BitInt)
SUGAR_FREE_TYPE(ObjCInterface)
SUGAR_FREE_TYPE(SubstTemplateTypeParmPack)
- SUGAR_FREE_TYPE(SubstBuiltinTemplatePack)
SUGAR_FREE_TYPE(UnresolvedUsing)
SUGAR_FREE_TYPE(HLSLAttributedResource)
SUGAR_FREE_TYPE(HLSLInlineSpirv)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6299efaf6bbfc..315ead9ef0105 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1842,14 +1842,6 @@ ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
*ReplacedOrErr, T->getIndex(), T->getFinal(), *ToArgumentPack);
}
-ExpectedType ASTNodeImporter::VisitSubstBuiltinTemplatePackType(
- const SubstBuiltinTemplatePackType *T) {
- Expected<TemplateArgument> ToArgumentPack = import(T->getArgumentPack());
- if (!ToArgumentPack)
- return ToArgumentPack.takeError();
- return Importer.getToContext().getSubstBuiltinTemplatePack(*ToArgumentPack);
-}
-
ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
auto ToTemplateOrErr = import(T->getTemplateName());
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6d83de384ee10..096bc6c8ca5b3 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1337,14 +1337,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
- case Type::SubstBuiltinTemplatePack: {
- const auto *Subst1 = cast<SubstBuiltinTemplatePackType>(T1);
- const auto *Subst2 = cast<SubstBuiltinTemplatePackType>(T2);
- if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(),
- Subst2->getArgumentPack()))
- return false;
- break;
- }
case Type::SubstTemplateTypeParmPack: {
const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index b91b4670c63a3..8a6fb3391c13f 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -307,9 +307,8 @@ bool TemplateDecl::hasAssociatedConstraints() const {
bool TemplateDecl::isTypeAlias() const {
switch (getKind()) {
case TemplateDecl::TypeAliasTemplate:
- return true;
case TemplateDecl::BuiltinTemplate:
- return !cast<BuiltinTemplateDecl>(this)->isPackProducingBuiltinTemplate();
+ return true;
default:
return false;
};
@@ -1599,16 +1598,6 @@ BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
createBuiltinTemplateParameterList(C, DC, BTK)),
BTK(BTK) {}
-bool BuiltinTemplateDecl::isPackProducingBuiltinTemplate() const {
- return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
-}
-
-bool clang::isPackProducingBuiltinTemplateName(TemplateName N) {
- auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
- N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
- return T && T->isPackProducingBuiltinTemplate();
-}
-
TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
QualType T,
const APValue &V) {
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 112678fb2714a..a7380a19e3607 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2444,13 +2444,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::CountAttributed:
llvm_unreachable("type is illegal as a nested name specifier");
- case Type::SubstBuiltinTemplatePack:
- // FIXME: not clear how to mangle this!
- // template <class T...> class A {
- // template <class U...> void foo(__builtin_dedup_pack<T...>(*)(U) x...);
- // };
- Out << "_SUBSTBUILTINPACK_";
- break;
case Type::SubstTemplateTypeParmPack:
// FIXME: not clear how to mangle this!
// template <class T...> class A {
@@ -3898,14 +3891,6 @@ void CXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T) {
Out << "_SUBSTPACK_";
}
-void CXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T) {
- // FIXME: not clear how to mangle this!
- // template <class T...> class A {
- // template <class U...> void foo(__builtin_dedup_pack<T...>(*)(U) x...);
- // };
- Out << "_SUBSTBUILTINPACK_";
-}
-
// <type> ::= P <type> # pointer-to
void CXXNameMangler::mangleType(const PointerType *T) {
Out << 'P';
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index fc79ab1de24ff..241c7c35fcc83 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3383,11 +3383,6 @@ void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,
Error(Range.getBegin(), "substituted parameter pack") << Range;
}
-void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,
- Qualifiers, SourceRange Range) {
- Error(Range.getBegin(), "substituted builtin template pack") << Range;
-}
-
// <type> ::= <pointer-type>
// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
// # the E is required for 64-bit non-static pointers
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index a70bc5424009c..5fbf1999ed725 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4558,45 +4558,17 @@ void SubstTemplateTypeParmType::Profile(llvm::FoldingSetNodeID &ID,
ID.AddBoolean(Final);
}
-SubstPackType::SubstPackType(TypeClass Derived, QualType Canon,
- const TemplateArgument &ArgPack)
- : Type(Derived, Canon,
- TypeDependence::DependentInstantiation |
- TypeDependence::UnexpandedPack),
- Arguments(ArgPack.pack_begin()) {
- assert(llvm::all_of(
- ArgPack.pack_elements(),
- [](auto &P) { return P.getKind() == TemplateArgument::Type; }) &&
- "non-type argument to SubstPackType?");
- SubstPackTypeBits.NumArgs = ArgPack.pack_size();
-}
-
-TemplateArgument SubstPackType::getArgumentPack() const {
- return TemplateArgument(llvm::ArrayRef(Arguments, getNumArgs()));
-}
-
-void SubstPackType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getArgumentPack());
-}
-
-void SubstPackType::Profile(llvm::FoldingSetNodeID &ID,
- const TemplateArgument &ArgPack) {
- ID.AddInteger(ArgPack.pack_size());
- for (const auto &P : ArgPack.pack_elements())
- ID.AddPointer(P.getAsType().getAsOpaquePtr());
-}
-
SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType(
QualType Canon, Decl *AssociatedDecl, unsigned Index, bool Final,
const TemplateArgument &ArgPack)
- : SubstPackType(SubstTemplateTypeParmPack, Canon, ArgPack),
+ : Type(SubstTemplateTypeParmPack, Canon,
+ TypeDependence::DependentInstantiation |
+ TypeDependence::UnexpandedPack),
+ Arguments(ArgPack.pack_begin()),
AssociatedDeclAndFinal(AssociatedDecl, Final) {
+ SubstTemplateTypeParmPackTypeBits.Index = Index;
+ SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
assert(AssociatedDecl != nullptr);
-
- SubstPackTypeBits.SubstTemplTypeParmPackIndex = Index;
- assert(getNumArgs() == ArgPack.pack_size() &&
- "Parent bitfields in SubstPackType were overwritten."
- "Check NumSubstPackTypeBits.");
}
Decl *SubstTemplateTypeParmPackType::getAssociatedDecl() const {
@@ -4616,6 +4588,10 @@ IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const {
return getReplacedParameter()->getIdentifier();
}
+TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
+ return TemplateArgument(llvm::ArrayRef(Arguments, getNumArgs()));
+}
+
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAssociatedDecl(), getIndex(), getFinal(), getArgumentPack());
}
@@ -4627,13 +4603,11 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
ID.AddPointer(AssociatedDecl);
ID.AddInteger(Index);
ID.AddBoolean(Final);
- SubstPackType::Profile(ID, ArgPack);
+ ID.AddInteger(ArgPack.pack_size());
+ for (const auto &P : ArgPack.pack_elements())
+ ID.AddPointer(P.getAsType().getAsOpaquePtr());
}
-SubstBuiltinTemplatePackType::SubstBuiltinTemplatePackType(
- QualType Canon, const TemplateArgument &ArgPack)
- : SubstPackType(SubstBuiltinTemplatePack, Canon, ArgPack) {}
-
bool TemplateSpecializationType::anyDependentTemplateArguments(
const TemplateArgumentListInfo &Args,
ArrayRef<TemplateArgument> Converted) {
@@ -4657,28 +4631,18 @@ bool TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
return false;
}
-static TypeDependence
-getTemplateSpecializationTypeDependence(QualType Underlying, TemplateName T) {
- TypeDependence D = Underlying.isNull()
- ? TypeDependence::DependentInstantiation
- : toSemanticDependence(Underlying->getDependence());
- D |= toTypeDependence(T.getDependence()) & TypeDependence::UnexpandedPack;
- if (isPackProducingBuiltinTemplateName(T)) {
- if (Underlying.isNull()) // Dependent, will produce a pack on substitution.
- D |= TypeDependence::UnexpandedPack;
- else
- D |= (Underlying->getDependence() & TypeDependence::UnexpandedPack);
- }
- return D;
-}
-
TemplateSpecializationType::TemplateSpecializationType(
ElaboratedTypeKeyword Keyword, TemplateName T, bool IsAlias,
ArrayRef<TemplateArgument> Args, QualType Underlying)
- : TypeWithKeyword(Keyword, TemplateSpecialization,
- Underlying.isNull() ? QualType(this, 0)
- : Underlying.getCanonicalType(),
- getTemplateSpecializationTypeDependence(Underlying, T)),
+ : TypeWithKeyword(
+ Keyword, TemplateSpecialization,
+ Underlying.isNull() ? QualType(this, 0)
+ : Underlying.getCanonicalType(),
+ (Underlying.isNull()
+ ? TypeDependence::DependentInstantiation
+ : toSemanticDependence(Underlying->getDependence())) |
+ (toTypeDependence(T.getDependence()) &
+ TypeDependence::UnexpandedPack)),
Template(T) {
TemplateSpecializationTypeBits.NumArgs = Args.size();
TemplateSpecializationTypeBits.TypeAlias = IsAlias;
@@ -4724,12 +4688,6 @@ QualType TemplateSpecializationType::getAliasedType() const {
return *reinterpret_cast<const QualType *>(template_arguments().end());
}
-bool clang::TemplateSpecializationType::isSugared() const {
- return !isDependentType() || isCurrentInstantiation() || isTypeAlias() ||
- (isPackProducingBuiltinTemplateName(Template) &&
- isa<SubstBuiltinTemplatePackType>(*getCanonicalTypeInternal()));
-}
-
void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Ctx) {
Profile(ID, Template, template_arguments(),
@@ -5145,7 +5103,6 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::UnaryTransform:
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
- case Type::SubstBuiltinTemplatePack:
case Type::DependentName:
case Type::DependentTemplateSpecialization:
case Type::Auto:
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 52ff0d5b5771b..85242b69f0679 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -232,7 +232,6 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::Enum:
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
- case Type::SubstBuiltinTemplatePack:
case Type::DeducedTemplateSpecialization:
case Type::TemplateSpecialization:
case Type::InjectedClassName:
@@ -1732,15 +1731,6 @@ void TypePrinter::printSubstTemplateTypeParmAfter(
printAfter(T->getReplacementType(), OS);
}
-void TypePrinter::printSubstBuiltinTemplatePackBefore(
- const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
- IncludeStrongLifetimeRAII Strong(Policy);
- OS << "type-pack";
-}
-
-void TypePrinter::printSubstBuiltinTemplatePackAfter(
- const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
-
void TypePrinter::printSubstTemplateTypeParmPackBefore(
const SubstTemplateTypeParmPackType *T,
raw_ostream &OS) {
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 74aff0b804057..0c1cd8c2d75c8 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1310,8 +1310,6 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
}
}
- Result = Actions.ActOnTemplateTemplateArgument(Result);
-
// If this is a pack expansion, build it as such.
if (EllipsisLoc.isValid() && !Result.isInvalid())
Result = Actions.ActOnPackExpansion(Result, EllipsisLoc);
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index f114173a42c21..da85959c005fe 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -307,8 +307,7 @@ static UnsignedOrNone EvaluateFoldExpandedConstraintSize(
UnsignedOrNone NumExpansions = FE->getNumExpansions();
if (S.CheckParameterPacksForExpansion(
FE->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded, MLTAL,
- /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
- NumExpansions) ||
+ Expand, RetainExpansion, NumExpansions) ||
!Expand || RetainExpansion)
return std::nullopt;
@@ -1697,13 +1696,11 @@ bool FoldExpandedConstraint::AreCompatibleForSubsumption(
Sema::collectUnexpandedParameterPacks(const_cast<Expr *>(B.Pattern), BPacks);
for (const UnexpandedParameterPack &APack : APacks) {
- auto ADI = getDepthAndIndex(APack);
- if (!ADI)
- continue;
- auto It = llvm::find_if(BPacks, [&](const UnexpandedParameterPack &BPack) {
- return getDepthAndIndex(BPack) == ADI;
+ std::pair<unsigned, unsigned> DepthAndIndex = getDepthAndIndex(APack);
+ auto it = llvm::find_if(BPacks, [&](const UnexpandedParameterPack &BPack) {
+ return getDepthAndIndex(BPack) == DepthAndIndex;
});
- if (It != BPacks.end())
+ if (it != BPacks.end())
return true;
}
return false;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bb57968830a65..aa7de722c3e94 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18012,8 +18012,7 @@ DeclResult Sema::ActOnTemplatedFriendTag(
collectUnexpandedParameterPacks(QualifierLoc, Unexpanded);
unsigned FriendDeclDepth = TempParamLists.front()->getDepth();
for (UnexpandedParameterPack &U : Unexpanded) {
- if (std::optional<std::pair<unsigned, unsigned>> DI = getDepthAndIndex(U);
- DI && DI->first >= FriendDeclDepth) {
+ if (getDepthAndIndex(U).first >= FriendDeclDepth) {
auto *ND = dyn_cast<NamedDecl *>(U.first);
if (!ND)
ND = cast<const TemplateTypeParmType *>(U.first)->getDecl();
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 764625d24fe48..0edc850ae1b13 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -19,7 +19,6 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
-#include "clang/AST/TypeOrdering.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
@@ -317,12 +316,6 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
}
}
- if (isPackProducingBuiltinTemplateName(Template) &&
- S->getTemplateParamParent() == nullptr)
- Diag(Name.getBeginLoc(), diag::err_builtin_pack_outside_template) << TName;
- // Recover by returning the template, even though we would never be able to
- // substitute it.
-
TemplateResult = TemplateTy::make(Template);
return TemplateKind;
}
@@ -3484,28 +3477,6 @@ static QualType checkBuiltinTemplateIdType(
return Context.getHLSLInlineSpirvType(Opcode, Size, Alignment, Operands);
}
- case BTK__builtin_dedup_pack: {
- assert(Converted.size() == 1 && "__builtin_dedup_pack should be given "
- "a parameter pack");
- TemplateArgument Ts = Converted[0];
- // Delay the computation until we can compute the final result. We choose
- // not to remove the duplicates upfront before substitution to keep the code
- // simple.
- if (Ts.isDependent())
- return QualType();
- assert(Ts.getKind() == clang::TemplateArgument::Pack);
- llvm::SmallVector<TemplateArgument> OutArgs;
- llvm::SmallDenseSet<QualType> Seen;
- // Synthesize a new template argument list, removing duplicates.
- for (auto T : Ts.getPackAsArray()) {
- assert(T.getKind() == clang::TemplateArgument::Type);
- if (!Seen.insert(T.getAsType().getCanonicalType()).second)
- continue;
- OutArgs.push_back(T);
- }
- return Context.getSubstBuiltinTemplatePack(
- TemplateArgument::CreatePackCopy(Context, OutArgs));
- }
}
llvm_unreachable("unexpected BuiltinTemplateDecl!");
}
@@ -5868,29 +5839,6 @@ bool Sema::CheckTemplateArgumentList(
}
}
- // Check for builtins producing template packs in this context, we do not
- // support them yet.
- if (const NonTypeTemplateParmDecl *NTTP =
- dyn_cast<NonTypeTemplateParmDecl>(*Param);
- NTTP && NTTP->isPackExpansion()) {
- auto TL = NTTP->getTypeSourceInfo()
- ->getTypeLoc()
- .castAs<PackExpansionTypeLoc>();
- llvm::SmallVector<UnexpandedParameterPack> Unexpanded;
- collectUnexpandedParameterPacks(TL.getPatternLoc(), Unexpanded);
- for (const auto &UPP : Unexpanded) {
- auto *TST = UPP.first.dyn_cast<const TemplateSpecializationType *>();
- if (!TST)
- continue;
- assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
- // Expanding a built-in pack in this context is not yet supported.
- Diag(TL.getEllipsisLoc(),
- diag::err_unsupported_builtin_template_pack_expansion)
- << TST->getTemplateName();
- return true;
- }
- }
-
if (ArgIdx < NumArgs) {
TemplateArgumentLoc &ArgLoc = NewArgs[ArgIdx];
bool NonPackParameter =
@@ -6348,11 +6296,6 @@ bool UnnamedLocalNoLinkageFinder::VisitSubstTemplateTypeParmPackType(
return false;
}
-bool UnnamedLocalNoLinkageFinder::VisitSubstBuiltinTemplatePackType(
- const SubstBuiltinTemplatePackType *) {
- return false;
-}
-
bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
const TemplateSpecializationType*) {
return false;
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 93983bf6d1607..477f8c7541939 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -710,9 +710,6 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
// If the parameter is an alias template, there is nothing to deduce.
if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
return TemplateDeductionResult::Success;
- // Pack-producing templates can only be matched after substitution.
- if (isPackProducingBuiltinTemplateName(TNP))
- return TemplateDeductionResult::Success;
// Check whether the template argument is a dependent template-id.
if (isa<TemplateSpecializationType>(A.getCanonicalType())) {
@@ -931,11 +928,7 @@ class PackDeductionScope {
S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
unsigned Depth, Index;
- if (auto DI = getDepthAndIndex(Unexpanded[I]))
- std::tie(Depth, Index) = *DI;
- else
- continue;
-
+ std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
if (Depth == Info.getDeducedDepth())
AddPack(Index);
}
@@ -943,6 +936,7 @@ class PackDeductionScope {
// Look for unexpanded packs in the pattern.
Collect(Pattern);
+ assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
unsigned NumNamedPacks = Packs.size();
@@ -1864,7 +1858,6 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
- case Type::SubstBuiltinTemplatePack:
llvm_unreachable("Type nodes handled above");
case Type::Auto:
@@ -6974,12 +6967,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
= cast<SubstTemplateTypeParmPackType>(T);
if (Subst->getReplacedParameter()->getDepth() == Depth)
Used[Subst->getIndex()] = true;
- MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(), OnlyDeduced,
- Depth, Used);
- break;
- }
- case Type::SubstBuiltinTemplatePack: {
- MarkUsedTemplateParameters(Ctx, cast<SubstPackType>(T)->getArgumentPack(),
+ MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(),
OnlyDeduced, Depth, Used);
break;
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index fe1c5faba9e40..5e8dfd19fd6fa 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1459,7 +1459,6 @@ namespace {
bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
SourceRange PatternRange,
ArrayRef<UnexpandedParameterPack> Unexpanded,
- bool FailOnPackProducingTemplates,
bool &ShouldExpand, bool &RetainExpansion,
UnsignedOrNone &NumExpansions) {
if (SemaRef.CurrentInstantiationScope &&
@@ -1473,9 +1472,8 @@ namespace {
}
return getSema().CheckParameterPacksForExpansion(
- EllipsisLoc, PatternRange, Unexpanded, TemplateArgs,
- FailOnPackProducingTemplates, ShouldExpand, RetainExpansion,
- NumExpansions);
+ EllipsisLoc, PatternRange, Unexpanded, TemplateArgs, ShouldExpand,
+ RetainExpansion, NumExpansions);
}
void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
@@ -1517,21 +1515,6 @@ namespace {
}
}
- MultiLevelTemplateArgumentList ForgetSubstitution() {
- MultiLevelTemplateArgumentList New;
- New.addOuterRetainedLevels(this->TemplateArgs.getNumLevels());
-
- MultiLevelTemplateArgumentList Old =
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
- std::move(New);
- return Old;
- }
- void RememberSubstitution(MultiLevelTemplateArgumentList Old) {
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
- std::move(Old);
- }
-
TemplateArgument
getTemplateArgumentPackPatternForRewrite(const TemplateArgument &TA) {
if (TA.getKind() != TemplateArgument::Pack)
@@ -1714,26 +1697,6 @@ namespace {
return inherited::TransformTemplateArgument(Input, Output, Uneval);
}
- using TreeTransform::TransformTemplateSpecializationType;
- QualType
- TransformTemplateSpecializationType(TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL) {
- auto *T = TL.getTypePtr();
- if (!getSema().ArgPackSubstIndex || !T->isSugared() ||
- !isPackProducingBuiltinTemplateName(T->getTemplateName()))
- return TreeTransform::TransformTemplateSpecializationType(TLB, TL);
- // Look through sugar to get to the SubstBuiltinTemplatePackType that we
- // need to substitute into.
-
- // `TransformType` code below will handle picking the element from a pack
- // with the index `ArgPackSubstIndex`.
- // FIXME: add ability to represent sugarred type for N-th element of a
- // builtin pack and produce the sugar here.
- QualType R = TransformType(T->desugar());
- TLB.pushTrivial(getSema().getASTContext(), R, TL.getBeginLoc());
- return R;
- }
-
UnsignedOrNone ComputeSizeOfPackExprWithoutSubstitution(
ArrayRef<TemplateArgument> PackArgs) {
// Don't do this when rewriting template parameters for CTAD:
@@ -1783,9 +1746,6 @@ namespace {
TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
SubstTemplateTypeParmPackTypeLoc TL,
bool SuppressObjCLifetime);
- QualType
- TransformSubstBuiltinTemplatePackType(TypeLocBuilder &TLB,
- SubstBuiltinTemplatePackTypeLoc TL);
CXXRecordDecl::LambdaDependencyKind
ComputeLambdaDependency(LambdaScopeInfo *LSI) {
@@ -2023,7 +1983,6 @@ bool TemplateInstantiator::maybeInstantiateFunctionParameterToScope(
UnsignedOrNone NumExpansions = OrigNumExpansions;
if (TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
Pattern.getSourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true,
ShouldExpand, RetainExpansion, NumExpansions))
return true;
@@ -2760,17 +2719,6 @@ QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
getPackIndex(Pack), Arg, TL.getNameLoc());
}
-QualType TemplateInstantiator::TransformSubstBuiltinTemplatePackType(
- TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
- if (!getSema().ArgPackSubstIndex)
- return TreeTransform::TransformSubstBuiltinTemplatePackType(TLB, TL);
- auto &Sema = getSema();
- TemplateArgument Result = getPackSubstitutedTemplateArgument(
- Sema, TL.getTypePtr()->getArgumentPack());
- TLB.pushTrivial(Sema.getASTContext(), Result.getAsType(), TL.getBeginLoc());
- return Result.getAsType();
-}
-
static concepts::Requirement::SubstitutionDiagnostic *
createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
Sema::EntityPrinter Printer) {
@@ -3498,72 +3446,6 @@ bool Sema::SubstDefaultArgument(
return false;
}
-// See TreeTransform::PreparePackForExpansion for the relevant comment.
-// This function implements the same concept for base specifiers.
-static bool
-PreparePackForExpansion(Sema &S, const CXXBaseSpecifier &Base,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TypeSourceInfo *&Out, UnexpandedInfo &Info) {
- SourceRange BaseSourceRange = Base.getSourceRange();
- SourceLocation BaseEllipsisLoc = Base.getEllipsisLoc();
- Info.Ellipsis = Base.getEllipsisLoc();
- auto ComputeInfo = [&S, &TemplateArgs, BaseSourceRange, BaseEllipsisLoc](
- TypeSourceInfo *BaseTypeInfo,
- bool IsLateExpansionAttempt, UnexpandedInfo &Info) {
- // This is a pack expansion. See whether we should expand it now, or
- // wait until later.
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- S.collectUnexpandedParameterPacks(BaseTypeInfo->getTypeLoc(), Unexpanded);
- if (IsLateExpansionAttempt) {
- // Request expansion only when there is an opportunity to expand a pack
- // that required a substituion first.
- bool SawPackTypes =
- llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
- return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
- });
- if (!SawPackTypes) {
- Info.Expand = false;
- return false;
- }
- }
-
- // Determine whether the set of unexpanded parameter packs can and should be
- // expanded.
- Info.Expand = false;
- Info.RetainExpansion = false;
- Info.NumExpansions = std::nullopt;
- return S.CheckParameterPacksForExpansion(
- BaseEllipsisLoc, BaseSourceRange, Unexpanded, TemplateArgs,
- /*FailOnPackProducingTemplates=*/false, Info.Expand,
- Info.RetainExpansion, Info.NumExpansions);
- };
-
- if (ComputeInfo(Base.getTypeSourceInfo(), false, Info))
- return true;
-
- if (Info.Expand) {
- Out = Base.getTypeSourceInfo();
- return false;
- }
-
- // The resulting base specifier will (still) be a pack expansion.
- {
- Sema::ArgPackSubstIndexRAII SubstIndex(S, std::nullopt);
- Out = S.SubstType(Base.getTypeSourceInfo(), TemplateArgs,
- BaseSourceRange.getBegin(), DeclarationName());
- }
- if (!Out->getType()->containsUnexpandedParameterPack())
- return false;
-
- // Some packs will learn their length after substitution.
- // We may need to request their expansion.
- if (ComputeInfo(Out, /*IsLateExpansionAttempt=*/true, Info))
- return true;
- if (Info.Expand)
- Info.ExpandUnderForgetSubstitions = true;
- return false;
-}
-
bool
Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
CXXRecordDecl *Pattern,
@@ -3581,37 +3463,47 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
}
SourceLocation EllipsisLoc;
- TypeSourceInfo *BaseTypeLoc = nullptr;
+ TypeSourceInfo *BaseTypeLoc;
if (Base.isPackExpansion()) {
- UnexpandedInfo Info;
- if (PreparePackForExpansion(*this, Base, TemplateArgs, BaseTypeLoc,
- Info)) {
+ // This is a pack expansion. See whether we should expand it now, or
+ // wait until later.
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
+ Unexpanded);
+ bool ShouldExpand = false;
+ bool RetainExpansion = false;
+ UnsignedOrNone NumExpansions = std::nullopt;
+ if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(),
+ Base.getSourceRange(),
+ Unexpanded,
+ TemplateArgs, ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
Invalid = true;
continue;
}
// If we should expand this pack expansion now, do so.
- MultiLevelTemplateArgumentList EmptyList;
- const MultiLevelTemplateArgumentList *ArgsForSubst = &TemplateArgs;
- if (Info.ExpandUnderForgetSubstitions)
- ArgsForSubst = &EmptyList;
-
- if (Info.Expand) {
- for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
+ if (ShouldExpand) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgPackSubstIndexRAII SubstIndex(*this, I);
- TypeSourceInfo *Expanded =
- SubstType(BaseTypeLoc, *ArgsForSubst,
- Base.getSourceRange().getBegin(), DeclarationName());
- if (!Expanded) {
+ TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
+ TemplateArgs,
+ Base.getSourceRange().getBegin(),
+ DeclarationName());
+ if (!BaseTypeLoc) {
Invalid = true;
continue;
}
- if (CXXBaseSpecifier *InstantiatedBase = CheckBaseSpecifier(
- Instantiation, Base.getSourceRange(), Base.isVirtual(),
- Base.getAccessSpecifierAsWritten(), Expanded,
- SourceLocation()))
+ if (CXXBaseSpecifier *InstantiatedBase
+ = CheckBaseSpecifier(Instantiation,
+ Base.getSourceRange(),
+ Base.isVirtual(),
+ Base.getAccessSpecifierAsWritten(),
+ BaseTypeLoc,
+ SourceLocation()))
InstantiatedBases.push_back(InstantiatedBase);
else
Invalid = true;
@@ -3623,9 +3515,10 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
// The resulting base specifier will (still) be a pack expansion.
EllipsisLoc = Base.getEllipsisLoc();
Sema::ArgPackSubstIndexRAII SubstIndex(*this, std::nullopt);
- BaseTypeLoc =
- SubstType(BaseTypeLoc, *ArgsForSubst,
- Base.getSourceRange().getBegin(), DeclarationName());
+ BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
+ TemplateArgs,
+ Base.getSourceRange().getBegin(),
+ DeclarationName());
} else {
BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
TemplateArgs,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 681ee796440f3..6b423ce06523a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -133,9 +133,8 @@ static void instantiateDependentAlignedAttr(
// FIXME: Use the actual location of the ellipsis.
SourceLocation EllipsisLoc = Aligned->getLocation();
if (S.CheckParameterPacksForExpansion(EllipsisLoc, Aligned->getRange(),
- Unexpanded, TemplateArgs,
- /*FailOnPackProducingTemplates=*/true,
- Expand, RetainExpansion, NumExpansions))
+ Unexpanded, TemplateArgs, Expand,
+ RetainExpansion, NumExpansions))
return;
if (!Expand) {
@@ -1915,8 +1914,7 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
UnsignedOrNone NumExpansions = std::nullopt;
if (SemaRef.CheckParameterPacksForExpansion(
D->getEllipsisLoc(), D->getSourceRange(), Unexpanded,
- TemplateArgs, /*FailOnPackProducingTemplates=*/true,
- ShouldExpand, RetainExpansion, NumExpansions))
+ TemplateArgs, ShouldExpand, RetainExpansion, NumExpansions))
return nullptr;
assert(!RetainExpansion &&
@@ -3466,11 +3464,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
->getEllipsisLoc(),
SourceRange(TC->getConceptNameLoc(),
- TC->hasExplicitTemplateArgs()
- ? TC->getTemplateArgsAsWritten()->getRAngleLoc()
- : TC->getConceptNameInfo().getEndLoc()),
- Unexpanded, TemplateArgs, /*FailOnPackProducingTemplates=*/true,
- Expand, RetainExpansion, NumExpanded))
+ TC->hasExplicitTemplateArgs() ?
+ TC->getTemplateArgsAsWritten()->getRAngleLoc() :
+ TC->getConceptNameInfo().getEndLoc()),
+ Unexpanded, TemplateArgs, Expand, RetainExpansion, NumExpanded))
return nullptr;
}
}
@@ -3558,10 +3555,12 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
UnsignedOrNone OrigNumExpansions =
Expansion.getTypePtr()->getNumExpansions();
UnsignedOrNone NumExpansions = OrigNumExpansions;
- if (SemaRef.CheckParameterPacksForExpansion(
- Expansion.getEllipsisLoc(), Pattern.getSourceRange(), Unexpanded,
- TemplateArgs, /*FailOnPackProducingTemplates=*/true, Expand,
- RetainExpansion, NumExpansions))
+ if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(),
+ Pattern.getSourceRange(),
+ Unexpanded,
+ TemplateArgs,
+ Expand, RetainExpansion,
+ NumExpansions))
return nullptr;
if (Expand) {
@@ -3727,10 +3726,12 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
bool Expand = true;
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
- if (SemaRef.CheckParameterPacksForExpansion(
- D->getLocation(), TempParams->getSourceRange(), Unexpanded,
- TemplateArgs, /*FailOnPackProducingTemplates=*/true, Expand,
- RetainExpansion, NumExpansions))
+ if (SemaRef.CheckParameterPacksForExpansion(D->getLocation(),
+ TempParams->getSourceRange(),
+ Unexpanded,
+ TemplateArgs,
+ Expand, RetainExpansion,
+ NumExpansions))
return nullptr;
if (Expand) {
@@ -4002,9 +4003,8 @@ Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
if (SemaRef.CheckParameterPacksForExpansion(
- D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,
- /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
- NumExpansions))
+ D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,
+ Expand, RetainExpansion, NumExpansions))
return nullptr;
// This declaration cannot appear within a function template signature,
@@ -6401,10 +6401,12 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
bool ShouldExpand = false;
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
- if (CheckParameterPacksForExpansion(
- Init->getEllipsisLoc(), BaseTL.getSourceRange(), Unexpanded,
- TemplateArgs, /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions)) {
+ if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),
+ BaseTL.getSourceRange(),
+ Unexpanded,
+ TemplateArgs, ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
AnyErrors = true;
New->setInvalidDecl();
continue;
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 0f72d6a13ae06..377f2ed3552d3 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -65,41 +65,6 @@ class CollectUnexpandedParameterPacksVisitor
Unexpanded.push_back({T, Loc});
}
- bool addUnexpanded(const SubstBuiltinTemplatePackType *T,
- SourceLocation Loc = SourceLocation()) {
- Unexpanded.push_back({T, Loc});
- return true;
- }
-
- bool addUnexpanded(const TemplateSpecializationType *T,
- SourceLocation Loc = SourceLocation()) {
- assert(T->isCanonicalUnqualified() &&
- isPackProducingBuiltinTemplateName(T->getTemplateName()));
- Unexpanded.push_back({T, Loc});
- return true;
- }
-
- /// Returns true iff it handled the traversal. On false, the callers must
- /// traverse themselves.
- bool
- TryTraverseSpecializationProducingPacks(const TemplateSpecializationType *T,
- SourceLocation Loc) {
- if (!isPackProducingBuiltinTemplateName(T->getTemplateName()))
- return false;
- // Canonical types are inputs to the initial substitution. Report them and
- // do not recurse any further.
- if (T->isCanonicalUnqualified()) {
- addUnexpanded(T, Loc);
- return true;
- }
- // For sugared types, do not use the default traversal as it would be
- // looking at (now irrelevant) template arguments. Instead, look at the
- // result of substitution, it usually contains SubstPackType that needs to
- // be expanded further.
- DynamicRecursiveASTVisitor::TraverseType(T->desugar());
- return true;
- }
-
public:
explicit CollectUnexpandedParameterPacksVisitor(
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
@@ -158,23 +123,6 @@ class CollectUnexpandedParameterPacksVisitor
return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
}
- bool
- TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc T,
- bool TraverseQualifier) override {
- if (TryTraverseSpecializationProducingPacks(T.getTypePtr(),
- T.getBeginLoc()))
- return true;
- return DynamicRecursiveASTVisitor::TraverseTemplateSpecializationTypeLoc(
- T, TraverseQualifier);
- }
-
- bool TraverseTemplateSpecializationType(TemplateSpecializationType *T,
- bool TraverseQualfier) override {
- if (TryTraverseSpecializationProducingPacks(T, SourceLocation()))
- return true;
- return DynamicRecursiveASTVisitor::TraverseTemplateSpecializationType(T);
- }
-
/// Suppress traversal into Objective-C container literal
/// elements that are pack expansions.
bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override {
@@ -377,14 +325,6 @@ class CollectUnexpandedParameterPacksVisitor
return DynamicRecursiveASTVisitor::TraverseUnresolvedLookupExpr(E);
}
- bool TraverseSubstBuiltinTemplatePackType(SubstBuiltinTemplatePackType *T,
- bool TraverseQualifier) override {
- addUnexpanded(T);
- // Do not call into base implementation to supress traversal of the
- // substituted types.
- return true;
- }
-
#ifndef NDEBUG
bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) override {
ContainsIntermediatePacks = true;
@@ -705,23 +645,6 @@ void Sema::collectUnexpandedParameterPacks(
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
}
-ParsedTemplateArgument
-Sema::ActOnTemplateTemplateArgument(const ParsedTemplateArgument &Arg) {
- if (Arg.isInvalid())
- return Arg;
-
- // We do not allow to reference builtin templates that produce multiple
- // values, they would not have a well-defined semantics outside template
- // arguments.
- auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
- Arg.getAsTemplate().get().getAsTemplateDecl());
- if (T && T->isPackProducingBuiltinTemplate())
- diagnoseMissingTemplateArguments(Arg.getAsTemplate().get(),
- Arg.getNameLoc());
-
- return Arg;
-}
-
ParsedTemplateArgument
Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
SourceLocation EllipsisLoc) {
@@ -808,7 +731,7 @@ QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
if (!Pattern->containsUnexpandedParameterPack() &&
!Pattern->getContainedDeducedType()) {
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
- << PatternRange;
+ << PatternRange;
return QualType();
}
@@ -842,8 +765,7 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
bool Sema::CheckParameterPacksForExpansion(
SourceLocation EllipsisLoc, SourceRange PatternRange,
ArrayRef<UnexpandedParameterPack> Unexpanded,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- bool FailOnPackProducingTemplates, bool &ShouldExpand,
+ const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
bool &RetainExpansion, UnsignedOrNone &NumExpansions) {
ShouldExpand = true;
RetainExpansion = false;
@@ -859,31 +781,12 @@ bool Sema::CheckParameterPacksForExpansion(
IdentifierInfo *Name;
bool IsVarDeclPack = false;
FunctionParmPackExpr *BindingPack = nullptr;
- std::optional<unsigned> NumPrecomputedArguments;
- if (auto *TTP = ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
+ if (const TemplateTypeParmType *TTP =
+ ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
Depth = TTP->getDepth();
Index = TTP->getIndex();
Name = TTP->getIdentifier();
- } else if (auto *TST =
- ParmPack.first
- .dyn_cast<const TemplateSpecializationType *>()) {
- assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
- // Delay expansion, substitution is required to know the size.
- ShouldExpand = false;
- if (!FailOnPackProducingTemplates)
- continue;
-
- // It is not yet supported in certain contexts.
- return Diag(PatternRange.getBegin().isValid() ? PatternRange.getBegin()
- : EllipsisLoc,
- diag::err_unsupported_builtin_template_pack_expansion)
- << TST->getTemplateName();
- } else if (auto *S =
- ParmPack.first
- .dyn_cast<const SubstBuiltinTemplatePackType *>()) {
- Name = nullptr;
- NumPrecomputedArguments = S->getNumArgs();
} else {
NamedDecl *ND = cast<NamedDecl *>(ParmPack.first);
if (isa<VarDecl>(ND))
@@ -923,8 +826,6 @@ bool Sema::CheckParameterPacksForExpansion(
}
} else if (BindingPack) {
NewPackSize = BindingPack->getNumExpansions();
- } else if (NumPrecomputedArguments) {
- NewPackSize = *NumPrecomputedArguments;
} else {
// If we don't have a template argument at this depth/index, then we
// cannot expand the pack expansion. Make a note of this, but we still
@@ -1066,21 +967,6 @@ UnsignedOrNone Sema::getNumArgumentsInExpansionFromUnexpanded(
Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
Depth = TTP->getDepth();
Index = TTP->getIndex();
- } else if (auto *TST =
- Unexpanded[I]
- .first.dyn_cast<const TemplateSpecializationType *>()) {
- // This is a dependent pack, we are not ready to expand it yet.
- assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
- (void)TST;
- return std::nullopt;
- } else if (auto *PST =
- Unexpanded[I]
- .first
- .dyn_cast<const SubstBuiltinTemplatePackType *>()) {
- assert((!Result || *Result == PST->getNumArgs()) &&
- "inconsistent pack sizes");
- Result = PST->getNumArgs();
- continue;
} else {
NamedDecl *ND = cast<NamedDecl *>(Unexpanded[I].first);
if (isa<VarDecl>(ND)) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 1d14ead778446..13cc6f1b24792 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -45,7 +45,6 @@
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaPseudoObject.h"
#include "clang/Sema/SemaSYCL.h"
-#include "clang/Sema/Template.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -56,17 +55,6 @@ using namespace llvm::omp;
namespace clang {
using namespace sema;
-// This helper class is used to facilitate pack expansion during tree transform.
-struct UnexpandedInfo {
- SourceLocation Ellipsis;
- UnsignedOrNone OrigNumExpansions = std::nullopt;
-
- bool Expand = false;
- bool RetainExpansion = false;
- UnsignedOrNone NumExpansions = std::nullopt;
- bool ExpandUnderForgetSubstitions = false;
-};
-
/// A semantic tree transformation that allows one to transform one
/// abstract syntax tree into another.
///
@@ -304,7 +292,6 @@ class TreeTransform {
bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
SourceRange PatternRange,
ArrayRef<UnexpandedParameterPack> Unexpanded,
- bool FailOnPackProducingTemplates,
bool &ShouldExpand, bool &RetainExpansion,
UnsignedOrNone &NumExpansions) {
ShouldExpand = false;
@@ -327,27 +314,6 @@ class TreeTransform {
/// This routine is meant to be overridden by the template instantiator.
void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
- /// "Forget" the template substitution to allow transforming the AST without
- /// any template instantiations. This is used to expand template packs when
- /// their size is not known in advance (e.g. for builtins that produce type
- /// packs).
- MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
- void RememberSubstitution(MultiLevelTemplateArgumentList) {}
-
-private:
- struct ForgetSubstitutionRAII {
- Derived &Self;
- MultiLevelTemplateArgumentList Old;
-
- public:
- ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
- Old = Self.ForgetSubstitution();
- }
-
- ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
- };
-
-public:
/// Note to the derived class when a function parameter pack is
/// being expanded.
void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
@@ -694,19 +660,6 @@ class TreeTransform {
TemplateArgumentListInfo &Outputs,
bool Uneval = false);
- /// Checks if the argument pack from \p In will need to be expanded and does
- /// the necessary prework.
- /// Whether the expansion is needed is captured in Info.Expand.
- ///
- /// - When the expansion is required, \p Out will be a template pattern that
- /// would need to be expanded.
- /// - When the expansion must not happen, \p Out will be a pack that must be
- /// returned to the outputs directly.
- ///
- /// \return true iff the error occurred
- bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
- TemplateArgumentLoc &Out, UnexpandedInfo &Info);
-
/// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
void InventTemplateArgumentLoc(const TemplateArgument &Arg,
TemplateArgumentLoc &ArgLoc);
@@ -4508,10 +4461,11 @@ bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
bool RetainExpansion = false;
UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
UnsignedOrNone NumExpansions = OrigNumExpansions;
- if (getDerived().TryExpandParameterPacks(
- Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
- Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
- RetainExpansion, NumExpansions))
+ if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
+ Pattern->getSourceRange(),
+ Unexpanded,
+ Expand, RetainExpansion,
+ NumExpansions))
return true;
if (!Expand) {
@@ -5127,30 +5081,60 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
}
if (In.getArgument().isPackExpansion()) {
- UnexpandedInfo Info;
- TemplateArgumentLoc Prepared;
- if (PreparePackForExpansion(In, Uneval, Prepared, Info))
+ // We have a pack expansion, for which we will be substituting into
+ // the pattern.
+ SourceLocation Ellipsis;
+ UnsignedOrNone OrigNumExpansions = std::nullopt;
+ TemplateArgumentLoc Pattern
+ = getSema().getTemplateArgumentPackExpansionPattern(
+ In, Ellipsis, OrigNumExpansions);
+
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
+
+ // Determine whether the set of unexpanded parameter packs can and should
+ // be expanded.
+ bool Expand = true;
+ bool RetainExpansion = false;
+ UnsignedOrNone NumExpansions = OrigNumExpansions;
+ if (getDerived().TryExpandParameterPacks(Ellipsis,
+ Pattern.getSourceRange(),
+ Unexpanded,
+ Expand,
+ RetainExpansion,
+ NumExpansions))
return true;
- if (!Info.Expand) {
- Outputs.addArgument(Prepared);
+
+ if (!Expand) {
+ // The transform has determined that we should perform a simple
+ // transformation on the pack expansion, producing another pack
+ // expansion.
+ TemplateArgumentLoc OutPattern;
+ Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
+ if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
+ return true;
+
+ Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
+ NumExpansions);
+ if (Out.getArgument().isNull())
+ return true;
+
+ Outputs.addArgument(Out);
continue;
}
// The transform has determined that we should perform an elementwise
// expansion of the pattern. Do so.
- std::optional<ForgetSubstitutionRAII> ForgetSubst;
- if (Info.ExpandUnderForgetSubstitions)
- ForgetSubst.emplace(getDerived());
- for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
- TemplateArgumentLoc Out;
- if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
+ if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
return true;
if (Out.getArgument().containsUnexpandedParameterPack()) {
- Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
- Info.OrigNumExpansions);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
}
@@ -5160,15 +5144,14 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
// If we're supposed to retain a pack expansion, do so by temporarily
// forgetting the partially-substituted parameter pack.
- if (Info.RetainExpansion) {
+ if (RetainExpansion) {
ForgetPartiallySubstitutedPackRAII Forget(getDerived());
- TemplateArgumentLoc Out;
- if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
+ if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
return true;
- Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
- Info.OrigNumExpansions);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
@@ -5189,114 +5172,6 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
}
-// FIXME: Find ways to reduce code duplication for pack expansions.
-template <typename Derived>
-bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
- bool Uneval,
- TemplateArgumentLoc &Out,
- UnexpandedInfo &Info) {
- auto ComputeInfo = [this](TemplateArgumentLoc Arg,
- bool IsLateExpansionAttempt, UnexpandedInfo &Info,
- TemplateArgumentLoc &Pattern) {
- assert(Arg.getArgument().isPackExpansion());
- // We have a pack expansion, for which we will be substituting into the
- // pattern.
- Pattern = getSema().getTemplateArgumentPackExpansionPattern(
- Arg, Info.Ellipsis, Info.OrigNumExpansions);
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
- if (IsLateExpansionAttempt) {
- // Request expansion only when there is an opportunity to expand a pack
- // that required a substituion first.
- bool SawPackTypes =
- llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
- return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
- });
- if (!SawPackTypes) {
- Info.Expand = false;
- return false;
- }
- }
- assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
-
- // Determine whether the set of unexpanded parameter packs can and
- // should be expanded.
- Info.Expand = true;
- Info.RetainExpansion = false;
- Info.NumExpansions = Info.OrigNumExpansions;
- return getDerived().TryExpandParameterPacks(
- Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/false, Info.Expand,
- Info.RetainExpansion, Info.NumExpansions);
- };
-
- TemplateArgumentLoc Pattern;
- if (ComputeInfo(In, false, Info, Pattern))
- return true;
-
- if (Info.Expand) {
- Out = Pattern;
- return false;
- }
-
- // The transform has determined that we should perform a simple
- // transformation on the pack expansion, producing another pack
- // expansion.
- TemplateArgumentLoc OutPattern;
- std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
- std::in_place, getSema(), std::nullopt);
- if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
- return true;
-
- Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
- Info.NumExpansions);
- if (Out.getArgument().isNull())
- return true;
- SubstIndex.reset();
-
- if (!OutPattern.getArgument().containsUnexpandedParameterPack())
- return false;
-
- // Some packs will learn their length after substitution, e.g.
- // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
- // value of `T`.
- //
- // We only expand after we know sizes of all packs, check if this is the case
- // or not. However, we avoid a full template substitution and only do
- // expanstions after this point.
-
- // E.g. when substituting template arguments of tuple with {T -> int} in the
- // following example:
- // template <class T>
- // struct TupleWithInt {
- // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
- // };
- // TupleWithInt<int>::type y;
- // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
- // lenght and run `ComputeInfo()` to provide the necessary information to our
- // caller.
- //
- // Note that we may still have situations where builtin is not going to be
- // expanded. For example:
- // template <class T>
- // struct Foo {
- // template <class U> using tuple_with_t =
- // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
- // tuple_with_t<short>;
- // }
- // Because the substitution into `type` happens in dependent context, `type`
- // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
- // and the caller will not be able to expand it.
- ForgetSubstitutionRAII ForgetSubst(getDerived());
- if (ComputeInfo(Out, true, Info, OutPattern))
- return true;
- if (!Info.Expand)
- return false;
- Out = OutPattern;
- Info.ExpandUnderForgetSubstitions = true;
- return false;
-}
-
//===----------------------------------------------------------------------===//
// Type transformation
//===----------------------------------------------------------------------===//
@@ -6307,10 +6182,12 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
if (Unexpanded.size() > 0) {
OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
NumExpansions = OrigNumExpansions;
- if (getDerived().TryExpandParameterPacks(
- ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
- Unexpanded, /*FailOnPackProducingTemplates=*/true,
- ShouldExpand, RetainExpansion, NumExpansions)) {
+ if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
+ Pattern.getSourceRange(),
+ Unexpanded,
+ ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
return true;
}
} else {
@@ -6416,10 +6293,11 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
bool RetainExpansion = false;
- if (getDerived().TryExpandParameterPacks(
- Loc, SourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions)) {
+ if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
+ Unexpanded,
+ ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
return true;
}
@@ -6716,9 +6594,8 @@ bool TreeTransform<Derived>::TransformExceptionSpec(
// FIXME: Track the location of the ellipsis (and track source location
// information for the types in the exception specification in general).
if (getDerived().TryExpandParameterPacks(
- Loc, SourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
- NumExpansions))
+ Loc, SourceRange(), Unexpanded, Expand,
+ RetainExpansion, NumExpansions))
return true;
if (!Expand) {
@@ -7030,10 +6907,9 @@ TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
bool ShouldExpand = true;
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
- if (getDerived().TryExpandParameterPacks(
- TL.getEllipsisLoc(), SourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions))
+ if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
+ Unexpanded, ShouldExpand,
+ RetainExpansion, NumExpansions))
return QualType();
if (!ShouldExpand) {
Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
@@ -7255,11 +7131,6 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
return Result;
}
-template <typename Derived>
-QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
- TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
- return TransformTypeSpecType(TLB, TL);
-}
template<typename Derived>
QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
@@ -7986,9 +7857,8 @@ TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
if (getDerived().TryExpandParameterPacks(
- PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
- Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
- RetainExpansion, NumExpansions))
+ PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
+ Unexpanded, Expand, RetainExpansion, NumExpansions))
return QualType();
if (!Expand) {
@@ -14971,10 +14841,11 @@ TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
UnsignedOrNone OrigNumExpansions =
ExpansionTL.getTypePtr()->getNumExpansions();
UnsignedOrNone NumExpansions = OrigNumExpansions;
- if (getDerived().TryExpandParameterPacks(
- ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
- Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
- RetainExpansion, NumExpansions))
+ if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
+ PatternTL.getSourceRange(),
+ Unexpanded,
+ Expand, RetainExpansion,
+ NumExpansions))
return ExprError();
if (!Expand) {
@@ -15548,8 +15419,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
ExpansionTL.getTypePtr()->getNumExpansions();
UnsignedOrNone NumExpansions = OrigNumExpansions;
if (getDerived().TryExpandParameterPacks(
- ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
- Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
+ ExpansionTL.getEllipsisLoc(),
+ OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
RetainExpansion, NumExpansions))
return ExprError();
assert(!RetainExpansion && "Should not need to retain expansion after a "
@@ -15709,10 +15580,11 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
bool ShouldExpand = false;
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
- if (getDerived().TryExpandParameterPacks(
- C->getEllipsisLoc(), C->getLocation(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions)) {
+ if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
+ C->getLocation(),
+ Unexpanded,
+ ShouldExpand, RetainExpansion,
+ NumExpansions)) {
Invalid = true;
continue;
}
@@ -16226,10 +16098,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
bool ShouldExpand = false;
bool RetainExpansion = false;
UnsignedOrNone NumExpansions = std::nullopt;
- if (getDerived().TryExpandParameterPacks(
- E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions))
+ if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
+ Unexpanded,
+ ShouldExpand, RetainExpansion,
+ NumExpansions))
return ExprError();
// If we need to expand the pack, build a template argument from it and
@@ -16346,8 +16218,7 @@ TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
NumExpansions = std::nullopt;
if (getDerived().TryExpandParameterPacks(
E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, ShouldExpand,
- RetainExpansion, NumExpansions))
+ ShouldExpand, RetainExpansion, NumExpansions))
return true;
if (!ShouldExpand) {
Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
@@ -16453,10 +16324,11 @@ TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
bool RetainExpansion = false;
UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
NumExpansions = OrigNumExpansions;
- if (getDerived().TryExpandParameterPacks(
- E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
- /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
- NumExpansions))
+ if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
+ Pattern->getSourceRange(),
+ Unexpanded,
+ Expand, RetainExpansion,
+ NumExpansions))
return true;
if (!Expand) {
@@ -16690,10 +16562,9 @@ TreeTransform<Derived>::TransformObjCDictionaryLiteral(
UnsignedOrNone NumExpansions = OrigNumExpansions;
SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
OrigElement.Value->getEndLoc());
- if (getDerived().TryExpandParameterPacks(
- OrigElement.EllipsisLoc, PatternRange, Unexpanded,
- /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
- NumExpansions))
+ if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
+ PatternRange, Unexpanded, Expand,
+ RetainExpansion, NumExpansions))
return ExprError();
if (!Expand) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index b3111c3091a44..b38f4944bda76 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7500,11 +7500,6 @@ void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
TL.setNameLoc(readSourceLocation());
}
-void TypeLocReader::VisitSubstBuiltinTemplatePackTypeLoc(
- SubstBuiltinTemplatePackTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
-}
-
void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
SourceLocation ElaboratedKeywordLoc = readSourceLocation();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 87e462f179ce6..a7327397aa6d7 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -627,11 +627,6 @@ void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
addSourceLocation(TL.getNameLoc());
}
-void TypeLocWriter::VisitSubstBuiltinTemplatePackTypeLoc(
- SubstBuiltinTemplatePackTypeLoc TL) {
- addSourceLocation(TL.getNameLoc());
-}
-
void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
addSourceLocation(TL.getElaboratedKeywordLoc());
@@ -1065,7 +1060,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(TYPE_PACK_EXPANSION);
RECORD(TYPE_ATTRIBUTED);
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
- RECORD(TYPE_SUBST_BUILTIN_TEMPLATE_PACK);
RECORD(TYPE_AUTO);
RECORD(TYPE_UNARY_TRANSFORM);
RECORD(TYPE_ATOMIC);
diff --git a/clang/test/Import/builtin-template/Inputs/S.cpp b/clang/test/Import/builtin-template/Inputs/S.cpp
index 85c71f61b0220..d5c9a9ae0309d 100644
--- a/clang/test/Import/builtin-template/Inputs/S.cpp
+++ b/clang/test/Import/builtin-template/Inputs/S.cpp
@@ -14,13 +14,3 @@ using TypePackElement = __type_pack_element<i, T...>;
template <int i>
struct X;
-
-using X0 = X<0>;
-template <int I>
-using SameAsX = X<I>;
-
-template <template <class...> class Templ, class...Types>
-using TypePackDedup = Templ<__builtin_dedup_pack<Types...>...>;
-
-template <class ...Ts>
-struct TypeList {};
diff --git a/clang/test/Import/builtin-template/test.cpp b/clang/test/Import/builtin-template/test.cpp
index a9afbd1b316bf..590efad0c71dc 100644
--- a/clang/test/Import/builtin-template/test.cpp
+++ b/clang/test/Import/builtin-template/test.cpp
@@ -1,11 +1,9 @@
// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s -Xcc -DSEQ | FileCheck --check-prefix=CHECK-SEQ %s
// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s -Xcc -DPACK | FileCheck --check-prefix=CHECK-PACK %s
-// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s -Xcc -DDEDUP | FileCheck --check-prefix=CHECK-DEDUP %s
-// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s -Xcc -DPACK -Xcc -DSEQ -Xcc -DDEDUP | FileCheck --check-prefixes=CHECK-SEQ,CHECK-PACK,CHECK-DEDUP %s
+// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s -Xcc -DPACK -Xcc -DSEQ | FileCheck --check-prefixes=CHECK-SEQ,CHECK-PACK %s
// CHECK-SEQ: BuiltinTemplateDecl {{.+}} <<invalid sloc>> <invalid sloc> implicit __make_integer_seq{{$}}
// CHECK-PACK: BuiltinTemplateDecl {{.+}} <<invalid sloc>> <invalid sloc> implicit __type_pack_element{{$}}
-// CHECK-DEDUP: BuiltinTemplateDecl {{.+}} <<invalid sloc>> <invalid sloc> implicit __builtin_dedup_pack{{$}}
void expr() {
#ifdef SEQ
@@ -22,12 +20,4 @@ void expr() {
static_assert(__is_same(TypePackElement<0, X<0>, X<1>>, X<0>), "");
static_assert(__is_same(TypePackElement<1, X<0>, X<1>>, X<1>), "");
#endif
-
-#ifdef DEDUP
- static_assert(__is_same(TypePackDedup<TypeList>, TypeList<>), "");
- static_assert(__is_same(TypePackDedup<TypeList, int, double, int>, TypeList<int, double>), "");
- static_assert(!__is_same(TypePackDedup<TypeList, int, double, int>, TypeList<double, int>), "");
- static_assert(__is_same(TypePackDedup<TypeList, X<0>, X<1>, X<1>, X<2>, X<0>>, TypeList<X<0>, X<1>, X<2>>), "");
- static_assert(__is_same(TypePackDedup<TypeList, X0, SameAsX<1>, X<1>, X<0>>, TypeList<X<0>,X<1>>), "");
-#endif
}
diff --git a/clang/test/PCH/dedup_types.cpp b/clang/test/PCH/dedup_types.cpp
deleted file mode 100644
index d4b19b4411169..0000000000000
--- a/clang/test/PCH/dedup_types.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -o %t.pch
-// RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch
-
-// RUN: %clang_cc1 -std=c++14 -x c++-header %s -emit-pch -fpch-instantiate-templates -o %t.pch
-// RUN: %clang_cc1 -std=c++14 -x c++ /dev/null -include-pch %t.pch
-
-template <template <class...> class Templ, class...Types>
-using TypePackDedup = Templ<__builtin_dedup_pack<Types...>...>;
-
-template <class ...Ts>
-struct TypeList {};
-
-template <int i>
-struct X {};
-
-void fn1() {
- TypeList<int, double> l1 = TypePackDedup<TypeList, int, double, int>{};
- TypeList<> l2 = TypePackDedup<TypeList>{};
- TypeList<X<0>, X<1>> x1 = TypePackDedup<TypeList, X<0>, X<1>, X<0>, X<1>>{};
-}
diff --git a/clang/test/SemaCXX/pr100095.cpp b/clang/test/SemaCXX/pr100095.cpp
index 9b8c09cb82977..15913fec9d5ae 100644
--- a/clang/test/SemaCXX/pr100095.cpp
+++ b/clang/test/SemaCXX/pr100095.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
+// XFAIL: asserts
template <class> struct Pair;
template <class...> struct Tuple {
diff --git a/clang/test/SemaTemplate/dedup-types-builtin.cpp b/clang/test/SemaTemplate/dedup-types-builtin.cpp
deleted file mode 100644
index 860754da4d628..0000000000000
--- a/clang/test/SemaTemplate/dedup-types-builtin.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// RUN: %clang_cc1 %s -verify
-template <typename...> struct TypeList;
-
-// === Check results of the builtin.
-template <class>
-struct TemplateWrapper {
- static_assert(__is_same( // expected-error {{static assertion contains an unexpanded parameter pack}}
- TypeList<__builtin_dedup_pack<int, int*, int, double, float>>,
- TypeList<int, int*, double, float>));
-};
-
-template <template<typename ...> typename Templ, typename ...Types>
-struct Dependent {
- using empty_list = Templ<__builtin_dedup_pack<>...>;
- using same = Templ<__builtin_dedup_pack<Types...>...>;
- using twice = Templ<__builtin_dedup_pack<Types..., Types...>...>;
- using dep_only_types = TypeList<__builtin_dedup_pack<Types...>...>;
- using dep_only_template = Templ<__builtin_dedup_pack<int, double, int>...>;
-};
-
-// Check the reverse condition to make sure we see an error and not accidentally produced dependent expression.
-static_assert(!__is_same(Dependent<TypeList>::empty_list, TypeList<>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList>::same, TypeList<>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList>::twice, TypeList<>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList>::dep_only_types, TypeList<>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList>::dep_only_template, TypeList<int, double>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList, int*, double*, int*>::empty_list, TypeList<>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList, int*, double*, int*>::same, TypeList<int*, double*>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList, int*, double*, int*>::twice, TypeList<int*, double*>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList, int*, double*, int*>::dep_only_types, TypeList<int*, double*>)); // expected-error {{static assertion failed}}
-static_assert(!__is_same(Dependent<TypeList, int*, double*, int*>::dep_only_template, TypeList<int, double>)); // expected-error {{static assertion failed}}
-
-
-template <class ...T>
-using Twice = TypeList<T..., T...>;
-
-template <class>
-struct TwiceTemplateWrapper {
- static_assert(!__is_same(Twice<__builtin_dedup_pack<int, double, int>...>, TypeList<int, double, int, double>)); // expected-error {{static assertion failed}}
-
-};
-template struct TwiceTemplateWrapper<int>; // expected-note {{in instantiation of template class 'TwiceTemplateWrapper<int>' requested here}}
-
-template <int...> struct IntList;
-// Wrong kinds of template arguments.
-template <class> struct IntListTemplateWrapper {
- IntList<__builtin_dedup_pack<int>...>* wrong_template; // expected-error {{template argument for non-type template parameter must be an expression}}
- // expected-note at -4 {{template parameter is declared here}}
- TypeList<__builtin_dedup_pack<1, 2, 3>...>* wrong_template_args; // expected-error {{template argument for template type parameter must be a type}}
- // expected-note@* {{template parameter from hidden source}}
- __builtin_dedup_pack<> not_enough_args; // expected-error {{data member type contains an unexpanded parameter pack}}
- // expected-note@* {{template declaration from hidden source}}
- __builtin_dedup_pack missing_template_args; // expected-error {{use of template '__builtin_dedup_pack' requires template arguments}}
-};
-
-// Make sure various canonical / non-canonical type representations do not affect results
-// of the deduplication and the qualifiers do end up creating different types when C++ requires it.
-using Int = int;
-using CInt = const Int;
-using IntArray = Int[10];
-using CIntArray = Int[10];
-using IntPtr = int*;
-using CIntPtr = const int*;
-
-template <class>
-struct Foo {
- static_assert(
- !__is_same( // expected-error {{static assertion failed}}
- // expected-note@* {{in instantiation of template class 'Foo<int>'}}
- TypeList<__builtin_dedup_pack<
- Int, int,
- const int, const Int, CInt, const CInt,
- IntArray, Int[10], int[10],
- const IntArray, const int[10], CIntArray, const CIntArray,
- IntPtr, int*,
- const IntPtr, int* const,
- CIntPtr, const int*,
- const IntPtr*, int*const*,
- CIntPtr*, const int**,
- const CIntPtr*, const int* const*
- >...>,
- TypeList<int, const int, int[10], const int [10], int*, int* const, const int*, int*const *, const int**, const int*const*>),
- "");
-};
-
-template struct Foo<int>;
-
-// === Show an error when packs are used in non-template contexts.
-static_assert(!__is_same(TypeList<__builtin_dedup_pack<int>...>, TypeList<int>)); // expected-error {{outside}}
-// Non-dependent uses in template are fine, though.
-template <class T>
-struct NonDepInTemplate {
- static_assert(!__is_same(TypeList<__builtin_dedup_pack<int>...>, TypeList<int>)); // expected-error {{static assertion failed}}
-};
-template struct NonDepInTemplate<int>; // expected-note {{requested here}}
-
-template <template<class...> class T = __builtin_dedup_pack> // expected-error {{use of template '__builtin_dedup_pack' requires template arguments}}
- // expected-note@* {{template declaration from hidden source}}
-struct UseAsTemplate;
-template <template<class...> class>
-struct AcceptsTemplateArg;
-template <class>
-struct UseAsTemplateWrapper {
- AcceptsTemplateArg<__builtin_dedup_pack>* a; // expected-error {{use of template '__builtin_dedup_pack' requires template arguments}}
- // expected-note@* {{template declaration from hidden source}}
-};
-
-// === Check how expansions in various contexts behave.
-// The following cases are not supported yet, should produce an error.
-template <class... T>
-struct DedupBases : __builtin_dedup_pack<T...>... {};
-struct Base1 {
- int a1;
-};
-struct Base2 {
- int a2;
-};
-static_assert(DedupBases<Base1, Base1, Base2, Base1, Base2, Base2>{1, 2}.a1 != 1); // expected-error {{static assertion failed}} \
- // expected-note {{}}
-static_assert(DedupBases<Base1, Base1, Base2, Base1, Base2, Base2>{1, 2}.a2 != 2); // expected-error {{static assertion failed}} \
- // expected-note {{}}
-
-template <class ...T>
-constexpr int dedup_params(__builtin_dedup_pack<T...>... as) {
- return (as + ...);
-}
-static_assert(dedup_params<int, int, short, int, short, short>(1, 2)); // expected-error {{no matching function}} \
- // expected-note at -3 {{expansions of '__builtin_dedup_pack' are not supported here}}
-
-template <class ...T>
-constexpr int dedup_params_into_type_list(TypeList<__builtin_dedup_pack<T...>...> *, T... as) {
- return (as + ...);
-}
-static_assert(dedup_params_into_type_list(static_cast<TypeList<int,short,long>*>(nullptr), 1, short(1), 1, 1l, 1l) != 5); // expected-error {{static assertion failed}} \
- // expected-note {{expression evaluates}}
-
-template <class T, __builtin_dedup_pack<T, int>...> // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here}}
-struct InTemplateParams {};
-InTemplateParams<int> itp1;
-InTemplateParams<int, 1, 2, 3, 4, 5> itp2;
-
-template <class T>
-struct DeepTemplateParams {
- template <__builtin_dedup_pack<T, int>...> // expected-error {{expansions of '__builtin_dedup_pack' are not supported here}}
- struct Templ {};
-};
-DeepTemplateParams<int>::Templ<> dtp1; // expected-note {{requested here}} \
- // expected-error {{no template named 'Templ'}}
-
-
-template <class ...T>
-struct MemInitializers : T... {
- MemInitializers() : __builtin_dedup_pack<T...>()... {} // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here.}}
-};
-MemInitializers<> mi1; // expected-note {{in instantiation of member function}}
-MemInitializers<Base1, Base2> mi2; // expected-note {{in instantiation of member function}}
-
-template <class ...T>
-constexpr int dedup_in_expressions() {
- // counts the number of unique Ts.
- return ((1 + __builtin_dedup_pack<T...>()) + ...); // expected-error {{expansions of '__builtin_dedup_pack' are not supported here.}} \
- // expected-note at +3 {{in instantiation of function template specialization}}
-}
-static_assert(dedup_in_expressions<int, int, short, double, int, short, double, int>() == 3); // expected-error {{not an integral constant expression}}
-
-template <class ...T>
-void in_exception_spec() throw(__builtin_dedup_pack<T...>...); // expected-error{{C++17 does not allow dynamic exception specifications}} \
- // expected-note {{use 'noexcept}} \
- // expected-error{{expansions of '__builtin_dedup_pack' are not supported here.}}
-
-void test_in_exception_spec() {
- in_exception_spec<int, double, int>(); // expected-note {{instantiation of exception specification}}
-}
-
-template <class ...T>
-constexpr bool in_type_trait = __is_trivially_constructible(int, __builtin_dedup_pack<T...>...); // expected-error{{expansions of '__builtin_dedup_pack' are not supported here.}}
-
-static_assert(in_type_trait<int, int, int>); // expected-note{{in instantiation of variable template specialization}}
-
-template <class ...T>
-struct InFriends {
- friend __builtin_dedup_pack<T>...; // expected-warning {{variadic 'friend' declarations are a C++2c extension}} \
- // expected-error 2 {{expansions of '__builtin_dedup_pack' are not supported here.}} \
- // expected-note@* 2 {{in instantiation of template class}}
-
-};
-struct Friend1 {};
-struct Friend2 {};
-InFriends<> if1;
-InFriends<Friend1, Friend2> if2;
-
-template <class ...T>
-struct InUsingDecl {
- using __builtin_dedup_pack<T...>::func...; // expected-error 2 {{expansions of '__builtin_dedup_pack' are not supported here.}}
-};
-struct WithFunc1 { void func(); };
-struct WithFunc2 { void func(int); };
-InUsingDecl<> iu1; // expected-note {{in instantiation of template class}}
-InUsingDecl<WithFunc1, WithFunc2> iu2; // expected-note {{in instantiation of template class}}
-
-// Note: produces parsing errors and does not construct pack indexing.
-// Keep this commented out until the parser supports this.
-//
-// template <class ...T>
-// struct InPackIndexing {
-//
-// using type = __builtin_dedup_pack<T...>...[0];
-// };
-// static_assert(__is_same(InPackIndexing<int, int>, int));
-
-template <class ...T>
-struct LambdaInitCaptures {
- static constexpr int test() {
- [...foos=__builtin_dedup_pack<T...>()]{}; // expected-warning {{initialized lambda pack captures are a C++20 extension}} \
- // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here.}}
- return 3;
- }
-};
-static_assert(LambdaInitCaptures<>::test() == 3); // expected-note {{in instantiation of member function}}
-static_assert(LambdaInitCaptures<int, int, int>::test() == 3); // expected-note {{in instantiation of member function}}
-
-template <class ...T>
-struct alignas(__builtin_dedup_pack<T...>...) AlignAs {}; // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here.}}
-AlignAs<> aa1; // expected-note {{in instantiation of template class}}
-AlignAs<int, double> aa2; // expected-note {{in instantiation of template class}}
-
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index e1aa9bb0721f8..eb6be2b337519 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1900,7 +1900,6 @@ DEFAULT_TYPELOC_IMPL(Record, TagType)
DEFAULT_TYPELOC_IMPL(Enum, TagType)
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
-DEFAULT_TYPELOC_IMPL(SubstBuiltinTemplatePack, Type)
DEFAULT_TYPELOC_IMPL(Auto, Type)
DEFAULT_TYPELOC_IMPL(BitInt, Type)
DEFAULT_TYPELOC_IMPL(DependentBitInt, Type)
More information about the cfe-commits
mailing list