Skip to content

Commit 4cfc635

Browse files
committed
[clang] ASTContext: fix creation of UnaryTransformTypes
This makes sure UnaryTransformTypes are all uniqued, which makes the AST node more well behaved, and helps with aka suppression in diagnostics. This also makes sure a canonical UnaryTransformType round trips back to a canonical type when recreated from its components.
1 parent ddbb464 commit 4cfc635

File tree

4 files changed

+38
-51
lines changed

4 files changed

+38
-51
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
243243
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
244244
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
245245
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
246-
mutable llvm::FoldingSet<DependentUnaryTransformType>
247-
DependentUnaryTransformTypes;
246+
mutable llvm::FoldingSet<UnaryTransformType> UnaryTransformTypes;
248247
// An AutoType can have a dependency on another AutoType via its template
249248
// arguments. Since both dependent and dependency are on the same set,
250249
// we can end up in an infinite recursion when looking for a node if we used

clang/include/clang/AST/Type.h

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6003,7 +6003,7 @@ class PackIndexingType final
60036003
};
60046004

60056005
/// A unary type transform, which is a type constructed from another.
6006-
class UnaryTransformType : public Type {
6006+
class UnaryTransformType : public Type, public llvm::FoldingSetNode {
60076007
public:
60086008
enum UTTKind {
60096009
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum,
@@ -6037,28 +6037,16 @@ class UnaryTransformType : public Type {
60376037
static bool classof(const Type *T) {
60386038
return T->getTypeClass() == UnaryTransform;
60396039
}
6040-
};
6041-
6042-
/// Internal representation of canonical, dependent
6043-
/// __underlying_type(type) types.
6044-
///
6045-
/// This class is used internally by the ASTContext to manage
6046-
/// canonical, dependent types, only. Clients will only see instances
6047-
/// of this class via UnaryTransformType nodes.
6048-
class DependentUnaryTransformType : public UnaryTransformType,
6049-
public llvm::FoldingSetNode {
6050-
public:
6051-
DependentUnaryTransformType(const ASTContext &C, QualType BaseType,
6052-
UTTKind UKind);
60536040

60546041
void Profile(llvm::FoldingSetNodeID &ID) {
6055-
Profile(ID, getBaseType(), getUTTKind());
6042+
Profile(ID, getBaseType(), getUnderlyingType(), getUTTKind());
60566043
}
60576044

60586045
static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType,
6059-
UTTKind UKind) {
6060-
ID.AddPointer(BaseType.getAsOpaquePtr());
6061-
ID.AddInteger((unsigned)UKind);
6046+
QualType UnderlyingType, UTTKind UKind) {
6047+
BaseType.Profile(ID);
6048+
UnderlyingType.Profile(ID);
6049+
ID.AddInteger(UKind);
60626050
}
60636051
};
60646052

clang/lib/AST/ASTContext.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6422,36 +6422,41 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
64226422

64236423
/// getUnaryTransformationType - We don't unique these, since the memory
64246424
/// savings are minimal and these are rare.
6425-
QualType ASTContext::getUnaryTransformType(QualType BaseType,
6426-
QualType UnderlyingType,
6427-
UnaryTransformType::UTTKind Kind)
6428-
const {
6429-
UnaryTransformType *ut = nullptr;
6430-
6431-
if (BaseType->isDependentType()) {
6432-
// Look in the folding set for an existing type.
6433-
llvm::FoldingSetNodeID ID;
6434-
DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind);
6425+
QualType
6426+
ASTContext::getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
6427+
UnaryTransformType::UTTKind Kind) const {
64356428

6436-
void *InsertPos = nullptr;
6437-
DependentUnaryTransformType *Canon
6438-
= DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos);
6429+
llvm::FoldingSetNodeID ID;
6430+
UnaryTransformType::Profile(ID, BaseType, UnderlyingType, Kind);
64396431

6440-
if (!Canon) {
6441-
// Build a new, canonical __underlying_type(type) type.
6442-
Canon = new (*this, alignof(DependentUnaryTransformType))
6443-
DependentUnaryTransformType(*this, getCanonicalType(BaseType), Kind);
6444-
DependentUnaryTransformTypes.InsertNode(Canon, InsertPos);
6445-
}
6446-
ut = new (*this, alignof(UnaryTransformType))
6447-
UnaryTransformType(BaseType, QualType(), Kind, QualType(Canon, 0));
6432+
void *InsertPos = nullptr;
6433+
if (UnaryTransformType *UT =
6434+
UnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos))
6435+
return QualType(UT, 0);
6436+
6437+
QualType CanonType;
6438+
if (!BaseType->isDependentType()) {
6439+
CanonType = UnderlyingType.getCanonicalType();
64486440
} else {
6449-
QualType CanonType = getCanonicalType(UnderlyingType);
6450-
ut = new (*this, alignof(UnaryTransformType))
6451-
UnaryTransformType(BaseType, UnderlyingType, Kind, CanonType);
6441+
assert(UnderlyingType.isNull() || BaseType == UnderlyingType);
6442+
UnderlyingType = QualType();
6443+
if (QualType CanonBase = BaseType.getCanonicalType();
6444+
BaseType != CanonBase) {
6445+
CanonType = getUnaryTransformType(CanonBase, QualType(), Kind);
6446+
assert(CanonType.isCanonical());
6447+
6448+
// Find the insertion position again.
6449+
[[maybe_unused]] UnaryTransformType *UT =
6450+
UnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos);
6451+
assert(!UT && "broken canonicalization");
6452+
}
64526453
}
6453-
Types.push_back(ut);
6454-
return QualType(ut, 0);
6454+
6455+
auto *UT = new (*this, alignof(UnaryTransformType))
6456+
UnaryTransformType(BaseType, UnderlyingType, Kind, CanonType);
6457+
UnaryTransformTypes.InsertNode(UT, InsertPos);
6458+
Types.push_back(UT);
6459+
return QualType(UT, 0);
64556460
}
64566461

64576462
QualType ASTContext::getAutoTypeInternal(

clang/lib/AST/Type.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4127,11 +4127,6 @@ UnaryTransformType::UnaryTransformType(QualType BaseType,
41274127
: Type(UnaryTransform, CanonicalType, BaseType->getDependence()),
41284128
BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {}
41294129

4130-
DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C,
4131-
QualType BaseType,
4132-
UTTKind UKind)
4133-
: UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {}
4134-
41354130
TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
41364131
: Type(TC, can,
41374132
D->isDependentType() ? TypeDependence::DependentInstantiation

0 commit comments

Comments
 (0)