Skip to content

[clang] Compiler builtin for deduping a list of types #105817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/TransformTypeTraits.def
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ TRANSFORM_TYPE_TRAIT_DEF(RemoveReference, remove_reference_t)
TRANSFORM_TYPE_TRAIT_DEF(RemoveRestrict, remove_restrict)
TRANSFORM_TYPE_TRAIT_DEF(RemoveVolatile, remove_volatile)
TRANSFORM_TYPE_TRAIT_DEF(EnumUnderlyingType, underlying_type)
TRANSFORM_TYPE_TRAIT_DEF(DedupTemplateArgs, dedup_template_args)

#undef TRANSFORM_TYPE_TRAIT_DEF
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ class DeclSpec {
T == TST_class);
}
static bool isTransformTypeTrait(TST T) {
constexpr std::array<TST, 16> Traits = {
constexpr std::array<TST, 17> Traits = {
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait,
#include "clang/Basic/TransformTypeTraits.def"
};
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -14899,6 +14899,7 @@ class Sema final : public SemaBase {
QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind,
SourceLocation Loc);
QualType BuiltinEnumUnderlyingType(QualType BaseType, SourceLocation Loc);
QualType BuiltinDedupTemplateArgs(QualType BaseType, SourceLocation Loc);
QualType BuiltinAddPointer(QualType BaseType, SourceLocation Loc);
QualType BuiltinRemovePointer(QualType BaseType, SourceLocation Loc);
QualType BuiltinDecay(QualType BaseType, SourceLocation Loc);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
Expand All @@ -38,9 +40,12 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/TimeProfiler.h"

#include <iterator>
#include <optional>
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
#include <bitset>
#include <optional>

Expand Down Expand Up @@ -9584,6 +9585,33 @@ QualType Sema::BuiltinEnumUnderlyingType(QualType BaseType,
return GetEnumUnderlyingType(*this, BaseType, Loc);
}

QualType Sema::BuiltinDedupTemplateArgs(QualType BaseType, SourceLocation Loc) {
llvm::TimeTraceScope TimeTrace("BuiltinDedupTemplateArgs");
if (RequireCompleteType(Loc, BaseType,
diag::err_incomplete_type_used_in_type_trait_expr))
return QualType();
const ElaboratedType *ET = cast<ElaboratedType>(BaseType);
auto *TST = ET->getNamedType()->castAs<TemplateSpecializationType>();
if (!TST) {
Diag(Loc, diag::err_incomplete_type_used_in_type_trait_expr) << BaseType;
return QualType();
}
TemplateArgumentListInfo Args(Loc, Loc);
llvm::DenseSet<QualType> SeenArgTypes;
for (const auto &Arg : TST->template_arguments()) {
if (!SeenArgTypes.insert(Arg.getAsType().getCanonicalType()).second)
continue;
Args.addArgument(TemplateArgumentLoc(
Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)));
}
QualType DedupedTypes =
CheckTemplateIdType(TST->getTemplateName(), Loc, Args);
if (RequireCompleteType(Loc, DedupedTypes,
diag::err_incomplete_type_used_in_type_trait_expr))
return QualType();
return DedupedTypes;
}

QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) {
QualType Pointer = BaseType.isReferenceable() || BaseType->isVoidType()
? BuildPointerType(BaseType.getNonReferenceType(), Loc,
Expand Down Expand Up @@ -9758,6 +9786,10 @@ QualType Sema::BuildUnaryTransformType(QualType BaseType, UTTKind UKind,
Result = BuiltinEnumUnderlyingType(BaseType, Loc);
break;
}
case UnaryTransformType::DedupTemplateArgs: {
Result = BuiltinDedupTemplateArgs(BaseType, Loc);
break;
}
case UnaryTransformType::AddPointer: {
Result = BuiltinAddPointer(BaseType, Loc);
break;
Expand Down
7 changes: 7 additions & 0 deletions clang/test/SemaCXX/type-traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5014,3 +5014,10 @@ void remove_all_extents() {
using SomeArray = int[1][2];
static_assert(__is_same(remove_all_extents_t<const SomeArray>, const int));
}

template <class T> using dedup_template_args_t = __dedup_template_args(T);
template <typename... T> struct TypeList{};
void dedup_types() {
static_assert(__is_same(dedup_template_args_t<TypeList<int, int, double, int>>,
TypeList<int,double>));
}