[clang-repl] Use canonical types in QualTypeToString (#190528)

Use the canonical type when generating type strings to ensure sugared
(e.g. `AutoType`, `DecltypeType`) are resolved before calling
getFullyQualifiedType.

This will revert a few commits that were added to fix these assertions.

---------

Co-authored-by: Harald van Dijk <hdijk@accesssoftek.com>
This commit is contained in:
Devajith 2026-04-05 18:09:39 +02:00 committed by GitHub
parent 0b7f01ad51
commit ba286040c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 9 additions and 28 deletions

View file

@ -369,17 +369,6 @@ NestedNameSpecifier createNestedNameSpecifier(const ASTContext &Ctx,
/// versions of any template parameters.
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
bool WithGlobalNsPrefix) {
// Use the underlying deduced type for AutoType
if (const auto *AT = dyn_cast<AutoType>(QT.getTypePtr())) {
if (AT->isDeduced()) {
// Get the qualifiers.
Qualifiers Quals = QT.getQualifiers();
QT = AT->getDeducedType();
// Add back the qualifiers.
QT = Ctx.getQualifiedType(QT, Quals);
}
}
// In case of myType* we need to strip the pointer first, fully
// qualify and attach the pointer once again.
if (isa<PointerType>(QT.getTypePtr())) {
@ -450,17 +439,6 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
QT = Ctx.getQualifiedType(QT, Quals);
}
// Try to get to the underlying type for DecltypeType
while (const auto *DT = dyn_cast<DecltypeType>(QT.getTypePtr())) {
// Get the qualifiers.
Qualifiers Quals = QT.getQualifiers();
QualType Underlying = DT->getUnderlyingType();
if (Underlying.isNull() || Underlying->isDependentType())
break;
// Add back the qualifiers.
QT = Ctx.getQualifiedType(Underlying, Quals);
}
if (const auto *TST =
dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {

View file

@ -78,7 +78,7 @@ static std::string QualTypeToString(ASTContext &Ctx, QualType QT) {
!NonRefTy->isMemberPointerType())
return Canon.getAsString(Ctx.getPrintingPolicy());
if (const auto *TDTy = dyn_cast<TypedefType>(NonRefTy)) {
if (const auto *TDTy = dyn_cast<TypedefType>(Canon)) {
// FIXME: TemplateSpecializationType & SubstTemplateTypeParmType checks
// are predominately to get STL containers to print nicer and might be
// better handled in GetFullyQualifiedName.
@ -87,13 +87,12 @@ static std::string QualTypeToString(ASTContext &Ctx, QualType QT) {
// std::vector<Type>::value_type is a SubstTemplateTypeParmType
//
QualType SSDesugar = TDTy->getLocallyUnqualifiedSingleStepDesugaredType();
if (llvm::isa<SubstTemplateTypeParmType>(SSDesugar))
if (llvm::isa<SubstTemplateTypeParmType>(SSDesugar) ||
llvm::isa<TemplateSpecializationType>(SSDesugar))
return GetFullTypeName(Ctx, Canon);
else if (llvm::isa<TemplateSpecializationType>(SSDesugar))
return GetFullTypeName(Ctx, NonRefTy);
return DeclTypeToString(NonRefTy, TDTy->getDecl());
return DeclTypeToString(Canon, TDTy->getDecl());
}
return GetFullTypeName(Ctx, NonRefTy);
return GetFullTypeName(Ctx, Canon);
}
static std::string EnumToString(const Value &V) {

View file

@ -85,6 +85,10 @@ decltype(decl1) decl2; decl2
const decltype(N::D()) decl3; decl3
// CHECK-NEXT: (const N::D &) @0x{{[0-9a-f]+}}
// Check printing of UnaryTransformType (this used to assert)
__remove_extent(N::D)* decl4; decl4
// CHECK-NEXT: (N::D *)
// int i = 12;
// int &iref = i;
// iref