Skip to content

Commit d73f711

Browse files
committed
[clang] AST: remove DependentTemplateSpecializationType
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`.
1 parent 1efa997 commit d73f711

Some content is hidden

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

53 files changed

+797
-1324
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/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

clang/include/clang/AST/TypeBase.h

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,22 +2250,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
22502250
unsigned NumArgs;
22512251
};
22522252

2253-
class DependentTemplateSpecializationTypeBitfields {
2254-
friend class DependentTemplateSpecializationType;
2255-
2256-
LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
2257-
unsigned : NumTypeWithKeywordBits;
2258-
2259-
/// The number of template arguments named in this class template
2260-
/// specialization, which is expected to be able to hold at least 1024
2261-
/// according to [implimits]. However, as this limit is somewhat easy to
2262-
/// hit with template metaprogramming we'd prefer to keep it as large
2263-
/// as possible. At the moment it has been left as a non-bitfield since
2264-
/// this type safely fits in 64 bits as an unsigned, so there is no reason
2265-
/// to introduce the performance impact of a bitfield.
2266-
unsigned NumArgs;
2267-
};
2268-
22692253
class PackExpansionTypeBitfields {
22702254
friend class PackExpansionType;
22712255

@@ -2346,8 +2330,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
23462330
SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
23472331
SubstPackTypeBitfields SubstPackTypeBits;
23482332
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
2349-
DependentTemplateSpecializationTypeBitfields
2350-
DependentTemplateSpecializationTypeBits;
23512333
PackExpansionTypeBitfields PackExpansionTypeBits;
23522334
CountAttributedTypeBitfields CountAttributedTypeBits;
23532335
PresefinedSugarTypeBitfields PredefinedSugarTypeBits;
@@ -7366,9 +7348,9 @@ class TemplateSpecializationType : public TypeWithKeyword,
73667348
}
73677349

73687350
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
7369-
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
7370-
ArrayRef<TemplateArgument> Args, QualType Underlying,
7371-
const ASTContext &Context);
7351+
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
7352+
TemplateName T, ArrayRef<TemplateArgument> Args,
7353+
QualType Underlying, const ASTContext &Context);
73727354

73737355
static bool classof(const Type *T) {
73747356
return T->getTypeClass() == TemplateSpecialization;
@@ -7459,46 +7441,6 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
74597441
}
74607442
};
74617443

7462-
/// Represents a template specialization type whose template cannot be
7463-
/// resolved, e.g.
7464-
/// A<T>::template B<T>
7465-
class DependentTemplateSpecializationType : public TypeWithKeyword {
7466-
friend class ASTContext; // ASTContext creates these
7467-
7468-
DependentTemplateStorage Name;
7469-
7470-
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
7471-
const DependentTemplateStorage &Name,
7472-
ArrayRef<TemplateArgument> Args,
7473-
QualType Canon);
7474-
7475-
public:
7476-
const DependentTemplateStorage &getDependentTemplateName() const {
7477-
return Name;
7478-
}
7479-
7480-
ArrayRef<TemplateArgument> template_arguments() const {
7481-
return {reinterpret_cast<const TemplateArgument *>(this + 1),
7482-
DependentTemplateSpecializationTypeBits.NumArgs};
7483-
}
7484-
7485-
bool isSugared() const { return false; }
7486-
QualType desugar() const { return QualType(this, 0); }
7487-
7488-
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
7489-
Profile(ID, Context, getKeyword(), Name, template_arguments());
7490-
}
7491-
7492-
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
7493-
ElaboratedTypeKeyword Keyword,
7494-
const DependentTemplateStorage &Name,
7495-
ArrayRef<TemplateArgument> Args);
7496-
7497-
static bool classof(const Type *T) {
7498-
return T->getTypeClass() == DependentTemplateSpecialization;
7499-
}
7500-
};
7501-
75027444
/// Represents a pack expansion of types.
75037445
///
75047446
/// Pack expansions are part of C++11 variadic templates. A pack

0 commit comments

Comments
 (0)