Skip to content

Revert "[clang] Improved canonicalization for template specialization types" #135354

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

Merged
merged 1 commit into from
Apr 11, 2025
Merged
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
3 changes: 1 addition & 2 deletions clang-tools-extra/clangd/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,7 @@ QualType declaredType(const TypeDecl *D) {
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
if (const auto *Args = CTSD->getTemplateArgsAsWritten())
return Context.getTemplateSpecializationType(
TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
/*CanonicalArgs=*/std::nullopt);
TemplateName(CTSD->getSpecializedTemplate()), Args->arguments());
return Context.getTypeDeclType(D);
}

Expand Down
2 changes: 0 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ Improvements to Clang's diagnostics
- Clang now better preserves the sugared types of pointers to member.
- Clang now better preserves the presence of the template keyword with dependent
prefixes.
- Clang now in more cases avoids printing 'type-parameter-X-X' instead of the name of
the template parameter.
- Clang now respects the current language mode when printing expressions in
diagnostics. This fixes a bunch of `bool` being printed as `_Bool`, and also
a bunch of HLSL types being printed as their C++ equivalents.
Expand Down
46 changes: 15 additions & 31 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
const ASTContext&>
CanonTemplateTemplateParms;

TemplateTemplateParmDecl *
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;

/// The typedef for the __int128_t type.
mutable TypedefDecl *Int128Decl = nullptr;

Expand Down Expand Up @@ -1808,26 +1811,22 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool ParameterPack,
TemplateTypeParmDecl *ParmDecl = nullptr) const;

QualType getCanonicalTemplateSpecializationType(
TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
QualType getTemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> Args,
QualType Canon = QualType()) const;

QualType
getTemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
QualType Underlying = QualType()) const;
getCanonicalTemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> Args) const;

QualType
getTemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
QualType Canon = QualType()) const;
QualType getTemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgumentLoc> Args,
QualType Canon = QualType()) const;

TypeSourceInfo *getTemplateSpecializationTypeInfo(
TemplateName T, SourceLocation TLoc,
const TemplateArgumentListInfo &SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
QualType Canon = QualType()) const;
TypeSourceInfo *
getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
const TemplateArgumentListInfo &Args,
QualType Canon = QualType()) const;

QualType getParenType(QualType NamedType) const;

Expand Down Expand Up @@ -2943,21 +2942,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
const;

/// Canonicalize the given template argument list.
///
/// Returns true if any arguments were non-canonical, false otherwise.
bool
canonicalizeTemplateArguments(MutableArrayRef<TemplateArgument> Args) const;

/// Canonicalize the given TemplateTemplateParmDecl.
TemplateTemplateParmDecl *
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;

TemplateTemplateParmDecl *findCanonicalTemplateTemplateParmDeclInternal(
TemplateTemplateParmDecl *TTP) const;
TemplateTemplateParmDecl *insertCanonicalTemplateTemplateParmDeclInternal(
TemplateTemplateParmDecl *CanonTTP) const;

/// Type Query functions. If the type is an instance of the specified class,
/// return the Type pointer for the underlying maximally pretty type. This
/// is a member of ASTContext because this may need to do some amount of
Expand Down
5 changes: 1 addition & 4 deletions clang/include/clang/AST/PropertiesBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -877,14 +877,11 @@ let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
def : Property<"expression", ExprRef> {
let Read = [{ node.getAsExpr() }];
}
def : Property<"IsCanonical", Bool> {
let Read = [{ node.isCanonicalExpr() }];
}
def : Property<"isDefaulted", Bool> {
let Read = [{ node.getIsDefaulted() }];
}
def : Creator<[{
return TemplateArgument(expression, IsCanonical, isDefaulted);
return TemplateArgument(expression, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
Expand Down
13 changes: 2 additions & 11 deletions clang/include/clang/AST/TemplateBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,6 @@ class TemplateArgument {
unsigned Kind : 31;
LLVM_PREFERRED_TYPE(bool)
unsigned IsDefaulted : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned IsCanonicalExpr : 1;
uintptr_t V;
};
union {
Expand All @@ -189,8 +187,7 @@ class TemplateArgument {

public:
/// Construct an empty, invalid template argument.
constexpr TemplateArgument()
: TypeOrValue{Null, /*IsDefaulted=*/0, /*IsCanonicalExpr=*/0, /*V=*/0} {}
constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}

/// Construct a template type argument.
TemplateArgument(QualType T, bool isNullPtr = false,
Expand Down Expand Up @@ -265,10 +262,9 @@ class TemplateArgument {
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
/// occur in a non-dependent, canonical template argument list.
TemplateArgument(Expr *E, bool IsCanonical, bool IsDefaulted = false) {
explicit TemplateArgument(Expr *E, bool IsDefaulted = false) {
TypeOrValue.Kind = Expression;
TypeOrValue.IsDefaulted = IsDefaulted;
TypeOrValue.IsCanonicalExpr = IsCanonical;
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
}

Expand Down Expand Up @@ -411,11 +407,6 @@ class TemplateArgument {
return reinterpret_cast<Expr *>(TypeOrValue.V);
}

bool isCanonicalExpr() const {
assert(getKind() == Expression && "Unexpected kind");
return TypeOrValue.IsCanonicalExpr;
}

/// Iterator that traverses the elements of a template argument pack.
using pack_iterator = const TemplateArgument *;

Expand Down
7 changes: 4 additions & 3 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6676,9 +6676,10 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
/// replacement must, recursively, be one of these).
TemplateName Template;

TemplateSpecializationType(TemplateName T, bool IsAlias,
TemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> Args,
QualType Underlying);
QualType Canon,
QualType Aliased);

public:
/// Determine whether any of the given template arguments are dependent.
Expand Down Expand Up @@ -6746,7 +6747,7 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
ArrayRef<TemplateArgument> Args, QualType Underlying,
ArrayRef<TemplateArgument> Args,
const ASTContext &Context);

static bool classof(const Type *T) {
Expand Down
30 changes: 25 additions & 5 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -737,19 +737,39 @@ let Class = DependentAddressSpaceType in {
}

let Class = TemplateSpecializationType in {
def : Property<"dependent", Bool> {
let Read = [{ node->isDependentType() }];
}
def : Property<"templateName", TemplateName> {
let Read = [{ node->getTemplateName() }];
}
def : Property<"args", Array<TemplateArgument>> {
def : Property<"templateArguments", Array<TemplateArgument>> {
let Read = [{ node->template_arguments() }];
}
def : Property<"UnderlyingType", QualType> {
let Read = [{ node->isCanonicalUnqualified() ? QualType() :
node->desugar() }];
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isTypeAlias()
? std::optional<QualType>(node->getAliasedType())
: node->isCanonicalUnqualified()
? std::nullopt
: std::optional<QualType>(node->getCanonicalTypeInternal())
}];
}

def : Creator<[{
return ctx.getTemplateSpecializationType(templateName, args, std::nullopt, UnderlyingType);
QualType result;
if (!underlyingType) {
result = ctx.getCanonicalTemplateSpecializationType(templateName,
templateArguments);
} else {
result = ctx.getTemplateSpecializationType(templateName,
templateArguments,
*underlyingType);
}
if (dependent)
const_cast<Type *>(result.getTypePtr())
->addDependence(TypeDependence::DependentInstantiation);
return result;
}]>;
}

Expand Down
Loading
Loading