-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang] AST: remove DependentTemplateSpecializationType #158109
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
Conversation
@llvm/pr-subscribers-lldb @llvm/pr-subscribers-coroutines Author: Matheus Izvekov (mizvekov) ChangesA DependentTemplateSpecializationType (DTST) is basically just a TemplateSpecializationType (TST) with a hardcoded DependentTemplateName (DTN) as its TemplateName. This removes the DTST and replaces all uses of it with a TST, removing a lot of duplication in the implementation. Technically the hardcoded DTN is an optimization for a most common case, but the TST implementation is in better shape overall and with other optimizations, so this patch ends up being an overall performance positive: A DTST also didn't allow a template name representing a DTN that was substituted, such as from an alias template, while the TST does allow it by the simple fact it can hold an arbitrary TemplateName, so this patch also increases the amount of sugar retained, while still being faster overall. Example (from included test case): template<template<class> class TT> using T1 = TT<int>;
template<class T> using T2 = T1<T::template X>; Here we can now represent in the AST that Patch is 170.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/158109.diff 53 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 90539eaabbe03..24d346bdfaa53 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -350,6 +350,8 @@ class RenamerClangTidyVisitor
const TemplateDecl *Decl =
Loc.getTypePtr()->getTemplateName().getAsTemplateDecl(
/*IgnoreDeduced=*/true);
+ if (!Decl)
+ return true;
if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl))
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 32018d1bf3a84..8aae41420b83e 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -406,15 +406,6 @@ struct TargetFinder {
}
}
}
- void VisitDependentTemplateSpecializationType(
- const DependentTemplateSpecializationType *DTST) {
- if (Outer.Resolver) {
- for (const NamedDecl *ND :
- Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
- Outer.add(ND, Flags);
- }
- }
- }
void VisitTypedefType(const TypedefType *TT) {
if (shouldSkipTypedef(TT->getDecl()))
return;
@@ -455,11 +446,13 @@ struct TargetFinder {
// class template specializations have a (specialized) CXXRecordDecl.
else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
Outer.add(RD, Flags); // add(Decl) will despecialize if needed.
- else {
+ else if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
// fallback: the (un-specialized) declaration from primary template.
- if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
- Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
- }
+ Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
+ else if (Outer.Resolver)
+ for (const NamedDecl *ND :
+ Outer.Resolver->resolveTemplateSpecializationType(TST))
+ Outer.add(ND, Flags);
}
void
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {
@@ -900,15 +893,6 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
DeclRelation::Alias, Resolver)});
}
- void VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc L) {
- Refs.push_back(
- ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
- /*IsDecl=*/false,
- explicitReferenceTargets(
- DynTypedNode::create(L.getType()), {}, Resolver)});
- }
-
void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
Refs.push_back(
ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 2b151b1274428..ab720ebe6b47f 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -728,11 +728,6 @@ class CollectExtraHighlightings
return true;
}
- bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
- H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
- return true;
- }
-
bool VisitFunctionDecl(FunctionDecl *D) {
if (D->isOverloadedOperator()) {
const auto AddOpDeclToken = [&](SourceLocation Loc) {
@@ -1087,11 +1082,12 @@ class CollectExtraHighlightings
return true;
}
- bool VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc L) {
- H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
- .addModifier(HighlightingModifier::DependentName)
- .addModifier(HighlightingModifier::ClassScope);
+ bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
+ if (!L.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true))
+ H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
+ .addModifier(HighlightingModifier::DependentName)
+ .addModifier(HighlightingModifier::ClassScope);
H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
return true;
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index f369e1b0341e8..dd26182630ae1 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -1029,8 +1029,7 @@ TEST_F(TargetDeclTest, DependentTypes) {
template <typename T>
void foo(typename A<T>::template [[B]]<int>);
)cpp";
- EXPECT_DECLS("DependentTemplateSpecializationTypeLoc",
- "template <typename> struct B");
+ EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");
// Dependent name with recursive definition. We don't expect a
// result, but we shouldn't get into a stack overflow either.
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 0cbf9a080a3ce..7bbdc8ba00dca 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -321,6 +321,8 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
// TypeLoc visitors.
void reportType(SourceLocation RefLoc, NamedDecl *ND) {
+ if (!ND)
+ return;
// Reporting explicit references to types nested inside classes can cause
// issues, e.g. a type accessed through a derived class shouldn't require
// inclusion of the base.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 1c17333b722f8..b8f6de69bbb98 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -241,9 +241,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<UsingType> UsingTypes;
mutable llvm::FoldingSet<FoldingSetPlaceholder<TypedefType>> TypedefTypes;
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
- mutable llvm::DenseMap<llvm::FoldingSetNodeID,
- DependentTemplateSpecializationType *>
- DependentTemplateSpecializationTypes;
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
@@ -1904,7 +1901,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateTypeParmDecl *ParmDecl = nullptr) const;
QualType getCanonicalTemplateSpecializationType(
- TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
+ ElaboratedTypeKeyword Keyword, TemplateName T,
+ ArrayRef<TemplateArgument> CanonicalArgs) const;
QualType
getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
@@ -1935,13 +1933,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
NestedNameSpecifier NNS,
const IdentifierInfo *Name) const;
- QualType getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgumentLoc> Args) const;
- QualType getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args, bool IsCanonical = false) const;
-
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const;
/// Form a pack expansion type with the given pattern.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index fe08d637a1e1d..ea68cc70f9131 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -533,11 +533,6 @@ class ASTNodeTraverser
for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
dumpTemplateArgumentLoc(TL.getArgLoc(I));
}
- void VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL) {
- for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
- dumpTemplateArgumentLoc(TL.getArgLoc(I));
- }
void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 02581c8e73299..c1944487716de 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1192,13 +1192,6 @@ DEF_TRAVERSE_TYPE(DependentNameType, {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
})
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- const DependentTemplateStorage &S = T->getDependentTemplateName();
- if (TraverseQualifier)
- TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->template_arguments()));
-})
-
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
if (TraverseQualifier) {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
@@ -1546,15 +1539,6 @@ DEF_TRAVERSE_TYPELOC(DependentNameType, {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
})
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TraverseQualifier)
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
if (TraverseQualifier)
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index abb0669bff378..b6999a1b4e9b9 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -297,10 +297,10 @@ class TemplateName {
/// set of function templates, returns NULL.
TemplateDecl *getAsTemplateDecl(bool IgnoreDeduced = false) const;
- /// Retrieves the underlying template declaration that
+ /// Retrieves the underlying template name that
/// this template name refers to, along with the
/// deduced default arguments, if any.
- std::pair<TemplateDecl *, DefaultArguments>
+ std::pair<TemplateName, DefaultArguments>
getTemplateDeclAndDefaultArgs() const;
/// Retrieve the underlying, overloaded function template
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index db2ab04e4471c..9074992a3de8c 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -2250,22 +2250,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned NumArgs;
};
- class DependentTemplateSpecializationTypeBitfields {
- friend class DependentTemplateSpecializationType;
-
- LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
- unsigned : NumTypeWithKeywordBits;
-
- /// The number of template arguments named in this class template
- /// specialization, which is expected to be able to hold at least 1024
- /// according to [implimits]. However, as this limit is somewhat easy to
- /// hit with template metaprogramming we'd prefer to keep it as large
- /// as possible. At the moment it has been left as a non-bitfield since
- /// this type safely fits in 64 bits as an unsigned, so there is no reason
- /// to introduce the performance impact of a bitfield.
- unsigned NumArgs;
- };
-
class PackExpansionTypeBitfields {
friend class PackExpansionType;
@@ -2346,8 +2330,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
SubstPackTypeBitfields SubstPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
- DependentTemplateSpecializationTypeBitfields
- DependentTemplateSpecializationTypeBits;
PackExpansionTypeBitfields PackExpansionTypeBits;
CountAttributedTypeBitfields CountAttributedTypeBits;
PresefinedSugarTypeBitfields PredefinedSugarTypeBits;
@@ -7366,9 +7348,9 @@ class TemplateSpecializationType : public TypeWithKeyword,
}
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- ArrayRef<TemplateArgument> Args, QualType Underlying,
- const ASTContext &Context);
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ TemplateName T, ArrayRef<TemplateArgument> Args,
+ QualType Underlying, const ASTContext &Context);
static bool classof(const Type *T) {
return T->getTypeClass() == TemplateSpecialization;
@@ -7459,46 +7441,6 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
}
};
-/// Represents a template specialization type whose template cannot be
-/// resolved, e.g.
-/// A<T>::template B<T>
-class DependentTemplateSpecializationType : public TypeWithKeyword {
- friend class ASTContext; // ASTContext creates these
-
- DependentTemplateStorage Name;
-
- DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args,
- QualType Canon);
-
-public:
- const DependentTemplateStorage &getDependentTemplateName() const {
- return Name;
- }
-
- ArrayRef<TemplateArgument> template_arguments() const {
- return {reinterpret_cast<const TemplateArgument *>(this + 1),
- DependentTemplateSpecializationTypeBits.NumArgs};
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), Name, template_arguments());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- ElaboratedTypeKeyword Keyword,
- const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentTemplateSpecialization;
- }
-};
-
/// Represents a pack expansion of types.
///
/// Pack expansions are part of C++11 variadic templates. A pack
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index d52e10419e97a..38e8fba569396 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -2598,134 +2598,6 @@ class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
- // followed by a TemplateArgumentLocInfo[]
-};
-
-class DependentTemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- DependentTemplateSpecializationTypeLoc,
- DependentTemplateSpecializationType,
- DependentTemplateSpecializationLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
-
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!getLocalData()->QualifierData)
- return NestedNameSpecifierLoc();
-
- return NestedNameSpecifierLoc(
- getTypePtr()->getDependentTemplateName().getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- if (!QualifierLoc) {
- // Even if we have a nested-name-specifier in the dependent
- // template specialization type, we won't record the nested-name-specifier
- // location information when this type-source location information is
- // part of a nested-name-specifier.
- getLocalData()->QualifierData = nullptr;
- return;
- }
-
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getDependentTemplateName().getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
-
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getTemplateNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
-
- void setTemplateNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
-
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
-
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->template_arguments().size();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
-
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
- getArgLocInfo(i));
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
- else if (getQualifierLoc())
- return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
- else if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void copy(DependentTemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return alignof(TemplateArgumentLocInfo);
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
struct PackExpansionTypeLocInfo {
SourceLocation EllipsisLoc;
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 185a968217f97..b3932a67db69d 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -729,41 +729,6 @@ let Class = TemplateSpecializationType in {
}]>;
}
-let Class = DependentTemplateSpecializationType in {
- def : ReadHelper<[{
- const auto &dtn = node->getDependentTemplateName();
- auto name = dtn.getName();
- }]>;
-
- def : Property<"qualifier", NestedNameSpecifier> {
- let Read = [{ dtn.getQualifier() }];
- }
- def : Property<"identifier", Optional<Identifier>> {
- let Read = [{ makeOptionalFromPointer(name.getIdentifier()) }];
- }
- def : Property<"operatorKind", OverloadedOperatorKind> {
- let Conditional = [{ !identifier }];
- let Read = [{ name.getOperator() }];
- }
- def : Property<"HasTemplateKeyword", Bool> {
- let Read = [{ dtn.hasTemplateKeyword() }];
- }
-
- def : Property<"keyword", ElaboratedTypeKeyword> {
- ...
[truncated]
|
@llvm/pr-subscribers-clang-tidy Author: Matheus Izvekov (mizvekov) ChangesA DependentTemplateSpecializationType (DTST) is basically just a TemplateSpecializationType (TST) with a hardcoded DependentTemplateName (DTN) as its TemplateName. This removes the DTST and replaces all uses of it with a TST, removing a lot of duplication in the implementation. Technically the hardcoded DTN is an optimization for a most common case, but the TST implementation is in better shape overall and with other optimizations, so this patch ends up being an overall performance positive: A DTST also didn't allow a template name representing a DTN that was substituted, such as from an alias template, while the TST does allow it by the simple fact it can hold an arbitrary TemplateName, so this patch also increases the amount of sugar retained, while still being faster overall. Example (from included test case): template<template<class> class TT> using T1 = TT<int>;
template<class T> using T2 = T1<T::template X>; Here we can now represent in the AST that Patch is 170.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/158109.diff 53 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 90539eaabbe03..24d346bdfaa53 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -350,6 +350,8 @@ class RenamerClangTidyVisitor
const TemplateDecl *Decl =
Loc.getTypePtr()->getTemplateName().getAsTemplateDecl(
/*IgnoreDeduced=*/true);
+ if (!Decl)
+ return true;
if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl))
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 32018d1bf3a84..8aae41420b83e 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -406,15 +406,6 @@ struct TargetFinder {
}
}
}
- void VisitDependentTemplateSpecializationType(
- const DependentTemplateSpecializationType *DTST) {
- if (Outer.Resolver) {
- for (const NamedDecl *ND :
- Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
- Outer.add(ND, Flags);
- }
- }
- }
void VisitTypedefType(const TypedefType *TT) {
if (shouldSkipTypedef(TT->getDecl()))
return;
@@ -455,11 +446,13 @@ struct TargetFinder {
// class template specializations have a (specialized) CXXRecordDecl.
else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
Outer.add(RD, Flags); // add(Decl) will despecialize if needed.
- else {
+ else if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
// fallback: the (un-specialized) declaration from primary template.
- if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
- Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
- }
+ Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
+ else if (Outer.Resolver)
+ for (const NamedDecl *ND :
+ Outer.Resolver->resolveTemplateSpecializationType(TST))
+ Outer.add(ND, Flags);
}
void
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {
@@ -900,15 +893,6 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
DeclRelation::Alias, Resolver)});
}
- void VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc L) {
- Refs.push_back(
- ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
- /*IsDecl=*/false,
- explicitReferenceTargets(
- DynTypedNode::create(L.getType()), {}, Resolver)});
- }
-
void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
Refs.push_back(
ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 2b151b1274428..ab720ebe6b47f 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -728,11 +728,6 @@ class CollectExtraHighlightings
return true;
}
- bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
- H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
- return true;
- }
-
bool VisitFunctionDecl(FunctionDecl *D) {
if (D->isOverloadedOperator()) {
const auto AddOpDeclToken = [&](SourceLocation Loc) {
@@ -1087,11 +1082,12 @@ class CollectExtraHighlightings
return true;
}
- bool VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc L) {
- H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
- .addModifier(HighlightingModifier::DependentName)
- .addModifier(HighlightingModifier::ClassScope);
+ bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
+ if (!L.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true))
+ H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
+ .addModifier(HighlightingModifier::DependentName)
+ .addModifier(HighlightingModifier::ClassScope);
H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
return true;
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index f369e1b0341e8..dd26182630ae1 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -1029,8 +1029,7 @@ TEST_F(TargetDeclTest, DependentTypes) {
template <typename T>
void foo(typename A<T>::template [[B]]<int>);
)cpp";
- EXPECT_DECLS("DependentTemplateSpecializationTypeLoc",
- "template <typename> struct B");
+ EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");
// Dependent name with recursive definition. We don't expect a
// result, but we shouldn't get into a stack overflow either.
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 0cbf9a080a3ce..7bbdc8ba00dca 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -321,6 +321,8 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
// TypeLoc visitors.
void reportType(SourceLocation RefLoc, NamedDecl *ND) {
+ if (!ND)
+ return;
// Reporting explicit references to types nested inside classes can cause
// issues, e.g. a type accessed through a derived class shouldn't require
// inclusion of the base.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 1c17333b722f8..b8f6de69bbb98 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -241,9 +241,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<UsingType> UsingTypes;
mutable llvm::FoldingSet<FoldingSetPlaceholder<TypedefType>> TypedefTypes;
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
- mutable llvm::DenseMap<llvm::FoldingSetNodeID,
- DependentTemplateSpecializationType *>
- DependentTemplateSpecializationTypes;
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
@@ -1904,7 +1901,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateTypeParmDecl *ParmDecl = nullptr) const;
QualType getCanonicalTemplateSpecializationType(
- TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
+ ElaboratedTypeKeyword Keyword, TemplateName T,
+ ArrayRef<TemplateArgument> CanonicalArgs) const;
QualType
getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
@@ -1935,13 +1933,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
NestedNameSpecifier NNS,
const IdentifierInfo *Name) const;
- QualType getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgumentLoc> Args) const;
- QualType getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args, bool IsCanonical = false) const;
-
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const;
/// Form a pack expansion type with the given pattern.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index fe08d637a1e1d..ea68cc70f9131 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -533,11 +533,6 @@ class ASTNodeTraverser
for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
dumpTemplateArgumentLoc(TL.getArgLoc(I));
}
- void VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL) {
- for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
- dumpTemplateArgumentLoc(TL.getArgLoc(I));
- }
void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 02581c8e73299..c1944487716de 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1192,13 +1192,6 @@ DEF_TRAVERSE_TYPE(DependentNameType, {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
})
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- const DependentTemplateStorage &S = T->getDependentTemplateName();
- if (TraverseQualifier)
- TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->template_arguments()));
-})
-
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
if (TraverseQualifier) {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
@@ -1546,15 +1539,6 @@ DEF_TRAVERSE_TYPELOC(DependentNameType, {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
})
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TraverseQualifier)
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
if (TraverseQualifier)
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index abb0669bff378..b6999a1b4e9b9 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -297,10 +297,10 @@ class TemplateName {
/// set of function templates, returns NULL.
TemplateDecl *getAsTemplateDecl(bool IgnoreDeduced = false) const;
- /// Retrieves the underlying template declaration that
+ /// Retrieves the underlying template name that
/// this template name refers to, along with the
/// deduced default arguments, if any.
- std::pair<TemplateDecl *, DefaultArguments>
+ std::pair<TemplateName, DefaultArguments>
getTemplateDeclAndDefaultArgs() const;
/// Retrieve the underlying, overloaded function template
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index db2ab04e4471c..9074992a3de8c 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -2250,22 +2250,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned NumArgs;
};
- class DependentTemplateSpecializationTypeBitfields {
- friend class DependentTemplateSpecializationType;
-
- LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
- unsigned : NumTypeWithKeywordBits;
-
- /// The number of template arguments named in this class template
- /// specialization, which is expected to be able to hold at least 1024
- /// according to [implimits]. However, as this limit is somewhat easy to
- /// hit with template metaprogramming we'd prefer to keep it as large
- /// as possible. At the moment it has been left as a non-bitfield since
- /// this type safely fits in 64 bits as an unsigned, so there is no reason
- /// to introduce the performance impact of a bitfield.
- unsigned NumArgs;
- };
-
class PackExpansionTypeBitfields {
friend class PackExpansionType;
@@ -2346,8 +2330,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
SubstPackTypeBitfields SubstPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
- DependentTemplateSpecializationTypeBitfields
- DependentTemplateSpecializationTypeBits;
PackExpansionTypeBitfields PackExpansionTypeBits;
CountAttributedTypeBitfields CountAttributedTypeBits;
PresefinedSugarTypeBitfields PredefinedSugarTypeBits;
@@ -7366,9 +7348,9 @@ class TemplateSpecializationType : public TypeWithKeyword,
}
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- ArrayRef<TemplateArgument> Args, QualType Underlying,
- const ASTContext &Context);
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ TemplateName T, ArrayRef<TemplateArgument> Args,
+ QualType Underlying, const ASTContext &Context);
static bool classof(const Type *T) {
return T->getTypeClass() == TemplateSpecialization;
@@ -7459,46 +7441,6 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
}
};
-/// Represents a template specialization type whose template cannot be
-/// resolved, e.g.
-/// A<T>::template B<T>
-class DependentTemplateSpecializationType : public TypeWithKeyword {
- friend class ASTContext; // ASTContext creates these
-
- DependentTemplateStorage Name;
-
- DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args,
- QualType Canon);
-
-public:
- const DependentTemplateStorage &getDependentTemplateName() const {
- return Name;
- }
-
- ArrayRef<TemplateArgument> template_arguments() const {
- return {reinterpret_cast<const TemplateArgument *>(this + 1),
- DependentTemplateSpecializationTypeBits.NumArgs};
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), Name, template_arguments());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- ElaboratedTypeKeyword Keyword,
- const DependentTemplateStorage &Name,
- ArrayRef<TemplateArgument> Args);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentTemplateSpecialization;
- }
-};
-
/// Represents a pack expansion of types.
///
/// Pack expansions are part of C++11 variadic templates. A pack
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index d52e10419e97a..38e8fba569396 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -2598,134 +2598,6 @@ class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
- // followed by a TemplateArgumentLocInfo[]
-};
-
-class DependentTemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- DependentTemplateSpecializationTypeLoc,
- DependentTemplateSpecializationType,
- DependentTemplateSpecializationLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
-
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!getLocalData()->QualifierData)
- return NestedNameSpecifierLoc();
-
- return NestedNameSpecifierLoc(
- getTypePtr()->getDependentTemplateName().getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- if (!QualifierLoc) {
- // Even if we have a nested-name-specifier in the dependent
- // template specialization type, we won't record the nested-name-specifier
- // location information when this type-source location information is
- // part of a nested-name-specifier.
- getLocalData()->QualifierData = nullptr;
- return;
- }
-
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getDependentTemplateName().getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
-
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getTemplateNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
-
- void setTemplateNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
-
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
-
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->template_arguments().size();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
-
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
- getArgLocInfo(i));
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
- else if (getQualifierLoc())
- return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
- else if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void copy(DependentTemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return alignof(TemplateArgumentLocInfo);
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
struct PackExpansionTypeLocInfo {
SourceLocation EllipsisLoc;
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 185a968217f97..b3932a67db69d 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -729,41 +729,6 @@ let Class = TemplateSpecializationType in {
}]>;
}
-let Class = DependentTemplateSpecializationType in {
- def : ReadHelper<[{
- const auto &dtn = node->getDependentTemplateName();
- auto name = dtn.getName();
- }]>;
-
- def : Property<"qualifier", NestedNameSpecifier> {
- let Read = [{ dtn.getQualifier() }];
- }
- def : Property<"identifier", Optional<Identifier>> {
- let Read = [{ makeOptionalFromPointer(name.getIdentifier()) }];
- }
- def : Property<"operatorKind", OverloadedOperatorKind> {
- let Conditional = [{ !identifier }];
- let Read = [{ name.getOperator() }];
- }
- def : Property<"HasTemplateKeyword", Bool> {
- let Read = [{ dtn.hasTemplateKeyword() }];
- }
-
- def : Property<"keyword", ElaboratedTypeKeyword> {
- ...
[truncated]
|
d73f711
to
2630712
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a neat change. I only did a cursory review for now but I like the direct and did not spot anything jaring. We do need to be a bit more careful about the AST matcher changes though
A DependentTemplateSpecializationType (DTST) is basically just a TemplateSpecializationType (TST) with a hardcoded DependentTemplateName (DTN) as its TemplateName. This removes the DTST and replaces all uses of it with a TST, removing a lot of duplication in the implementation. Technically the hardcoded DTN is an optimization for a most common case, but the TST implementation is in better shape overall and with other optimizations, so this patch ends up being an overall performance positive: A DTST also didn't allow a template name representing a DependentTemplateName that was substituted from an alias templates, while the TST does by the simple fact it can hold an arbitrary TemplateName, so this patch also increases the amount of sugar retained, while still being faster overall. Example (from included test case): ```C++ template<template<class> class TT> using T1 = TT<int>; template<class T> using T2 = T1<T::template X>; ``` Here we can now represent in the AST that `TT` was substituted for the dependent template name `T::template X`.
2630712
to
ceecf58
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A DTST also didn't allow a template name representing a DTN that was substituted
Thanks, this is very useful for addressing a bug in our concept refactoring, which we found from stdexec.
A DependentTemplateSpecializationType (DTST) is basically just a TemplateSpecializationType (TST) with a hardcoded DependentTemplateName (DTN) as its TemplateName.
This removes the DTST and replaces all uses of it with a TST, removing a lot of duplication in the implementation.
Technically the hardcoded DTN is an optimization for a most common case, but the TST implementation is in better shape overall and with other optimizations, so this patch ends up being an overall performance positive:

A DTST also didn't allow a template name representing a DTN that was substituted, such as from an alias template, while the TST does allow it by the simple fact it can hold an arbitrary TemplateName, so this patch also increases the amount of sugar retained, while still being faster overall.
Example (from included test case):
Here we can now represent in the AST that
TT
was substituted for the dependent template nameT::template X
.