Skip to content

Commit ba9d1c4

Browse files
authored
[clang] AST: remove DependentTemplateSpecializationType (llvm#158109)
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: <img width="1465" height="38" alt="image" src="https://github.com/user-attachments/assets/084b0694-2839-427a-b664-eff400f780b5" /> 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): ```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`.
1 parent 615d07e commit ba9d1c4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+800
-1333
lines changed

clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ class RenamerClangTidyVisitor
350350
const TemplateDecl *Decl =
351351
Loc.getTypePtr()->getTemplateName().getAsTemplateDecl(
352352
/*IgnoreDeduced=*/true);
353+
if (!Decl)
354+
return true;
353355

354356
if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl))
355357
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -406,15 +406,6 @@ struct TargetFinder {
406406
}
407407
}
408408
}
409-
void VisitDependentTemplateSpecializationType(
410-
const DependentTemplateSpecializationType *DTST) {
411-
if (Outer.Resolver) {
412-
for (const NamedDecl *ND :
413-
Outer.Resolver->resolveTemplateSpecializationType(DTST)) {
414-
Outer.add(ND, Flags);
415-
}
416-
}
417-
}
418409
void VisitTypedefType(const TypedefType *TT) {
419410
if (shouldSkipTypedef(TT->getDecl()))
420411
return;
@@ -455,11 +446,13 @@ struct TargetFinder {
455446
// class template specializations have a (specialized) CXXRecordDecl.
456447
else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())
457448
Outer.add(RD, Flags); // add(Decl) will despecialize if needed.
458-
else {
449+
else if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
459450
// fallback: the (un-specialized) declaration from primary template.
460-
if (auto *TD = TST->getTemplateName().getAsTemplateDecl())
461-
Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
462-
}
451+
Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
452+
else if (Outer.Resolver)
453+
for (const NamedDecl *ND :
454+
Outer.Resolver->resolveTemplateSpecializationType(TST))
455+
Outer.add(ND, Flags);
463456
}
464457
void
465458
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {
@@ -900,15 +893,6 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
900893
DeclRelation::Alias, Resolver)});
901894
}
902895

903-
void VisitDependentTemplateSpecializationTypeLoc(
904-
DependentTemplateSpecializationTypeLoc L) {
905-
Refs.push_back(
906-
ReferenceLoc{L.getQualifierLoc(), L.getTemplateNameLoc(),
907-
/*IsDecl=*/false,
908-
explicitReferenceTargets(
909-
DynTypedNode::create(L.getType()), {}, Resolver)});
910-
}
911-
912896
void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
913897
Refs.push_back(
914898
ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),

clang-tools-extra/clangd/SemanticHighlighting.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -728,11 +728,6 @@ class CollectExtraHighlightings
728728
return true;
729729
}
730730

731-
bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
732-
H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
733-
return true;
734-
}
735-
736731
bool VisitFunctionDecl(FunctionDecl *D) {
737732
if (D->isOverloadedOperator()) {
738733
const auto AddOpDeclToken = [&](SourceLocation Loc) {
@@ -1087,11 +1082,12 @@ class CollectExtraHighlightings
10871082
return true;
10881083
}
10891084

1090-
bool VisitDependentTemplateSpecializationTypeLoc(
1091-
DependentTemplateSpecializationTypeLoc L) {
1092-
H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
1093-
.addModifier(HighlightingModifier::DependentName)
1094-
.addModifier(HighlightingModifier::ClassScope);
1085+
bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
1086+
if (!L.getTypePtr()->getTemplateName().getAsTemplateDecl(
1087+
/*IgnoreDeduced=*/true))
1088+
H.addToken(L.getTemplateNameLoc(), HighlightingKind::Type)
1089+
.addModifier(HighlightingModifier::DependentName)
1090+
.addModifier(HighlightingModifier::ClassScope);
10951091
H.addAngleBracketTokens(L.getLAngleLoc(), L.getRAngleLoc());
10961092
return true;
10971093
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,7 @@ TEST_F(TargetDeclTest, DependentTypes) {
10291029
template <typename T>
10301030
void foo(typename A<T>::template [[B]]<int>);
10311031
)cpp";
1032-
EXPECT_DECLS("DependentTemplateSpecializationTypeLoc",
1033-
"template <typename> struct B");
1032+
EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> struct B");
10341033

10351034
// Dependent name with recursive definition. We don't expect a
10361035
// result, but we shouldn't get into a stack overflow either.

clang-tools-extra/include-cleaner/lib/WalkAST.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
321321

322322
// TypeLoc visitors.
323323
void reportType(SourceLocation RefLoc, NamedDecl *ND) {
324+
if (!ND)
325+
return;
324326
// Reporting explicit references to types nested inside classes can cause
325327
// issues, e.g. a type accessed through a derived class shouldn't require
326328
// inclusion of the base.

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,9 @@ AST Matchers
458458
following the corresponding changes in the clang AST.
459459
- Ensure ``hasBitWidth`` doesn't crash on bit widths that are dependent on template
460460
parameters.
461-
461+
- Remove the ``dependentTemplateSpecializationType`` matcher, as the
462+
corresponding AST node was removed. This matcher was never very useful, since
463+
there was no way to match on its template name.
462464
- Add a boolean member ``IgnoreSystemHeaders`` to ``MatchFinderOptions``. This
463465
allows it to ignore nodes in system headers when traversing the AST.
464466

clang/include/clang/AST/ASTContext.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
241241
mutable llvm::FoldingSet<UsingType> UsingTypes;
242242
mutable llvm::FoldingSet<FoldingSetPlaceholder<TypedefType>> TypedefTypes;
243243
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
244-
mutable llvm::DenseMap<llvm::FoldingSetNodeID,
245-
DependentTemplateSpecializationType *>
246-
DependentTemplateSpecializationTypes;
247244
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
248245
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
249246
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
@@ -1904,7 +1901,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
19041901
TemplateTypeParmDecl *ParmDecl = nullptr) const;
19051902

19061903
QualType getCanonicalTemplateSpecializationType(
1907-
TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
1904+
ElaboratedTypeKeyword Keyword, TemplateName T,
1905+
ArrayRef<TemplateArgument> CanonicalArgs) const;
19081906

19091907
QualType
19101908
getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
@@ -1935,13 +1933,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
19351933
NestedNameSpecifier NNS,
19361934
const IdentifierInfo *Name) const;
19371935

1938-
QualType getDependentTemplateSpecializationType(
1939-
ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
1940-
ArrayRef<TemplateArgumentLoc> Args) const;
1941-
QualType getDependentTemplateSpecializationType(
1942-
ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
1943-
ArrayRef<TemplateArgument> Args, bool IsCanonical = false) const;
1944-
19451936
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const;
19461937

19471938
/// Form a pack expansion type with the given pattern.

clang/include/clang/AST/ASTNodeTraverser.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,6 @@ class ASTNodeTraverser
533533
for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
534534
dumpTemplateArgumentLoc(TL.getArgLoc(I));
535535
}
536-
void VisitDependentTemplateSpecializationTypeLoc(
537-
DependentTemplateSpecializationTypeLoc TL) {
538-
for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
539-
dumpTemplateArgumentLoc(TL.getArgLoc(I));
540-
}
541536

542537
void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
543538

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,13 +1192,6 @@ DEF_TRAVERSE_TYPE(DependentNameType, {
11921192
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
11931193
})
11941194

1195-
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
1196-
const DependentTemplateStorage &S = T->getDependentTemplateName();
1197-
if (TraverseQualifier)
1198-
TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
1199-
TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1200-
})
1201-
12021195
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
12031196
if (TraverseQualifier) {
12041197
TRY_TO(TraverseTemplateName(T->getTemplateName()));
@@ -1546,15 +1539,6 @@ DEF_TRAVERSE_TYPELOC(DependentNameType, {
15461539
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
15471540
})
15481541

1549-
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
1550-
if (TraverseQualifier)
1551-
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1552-
1553-
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1554-
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1555-
}
1556-
})
1557-
15581542
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
15591543
if (TraverseQualifier)
15601544
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));

clang/include/clang/AST/TemplateName.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,10 @@ class TemplateName {
297297
/// set of function templates, returns NULL.
298298
TemplateDecl *getAsTemplateDecl(bool IgnoreDeduced = false) const;
299299

300-
/// Retrieves the underlying template declaration that
300+
/// Retrieves the underlying template name that
301301
/// this template name refers to, along with the
302302
/// deduced default arguments, if any.
303-
std::pair<TemplateDecl *, DefaultArguments>
303+
std::pair<TemplateName, DefaultArguments>
304304
getTemplateDeclAndDefaultArgs() const;
305305

306306
/// Retrieve the underlying, overloaded function template

0 commit comments

Comments
 (0)