Skip to content

Commit 3f4fc1d

Browse files
committed
[clang] ASTContext: make DecltypeType creation more well-behaved
This makes sure a canonical DecltypeType round-trips back to a canonical type when rebuilt from its components.
1 parent 8006825 commit 3f4fc1d

File tree

3 files changed

+26
-24
lines changed

3 files changed

+26
-24
lines changed

clang/include/clang/AST/Type.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5918,7 +5918,7 @@ class DecltypeType : public Type {
59185918
/// of this class via DecltypeType nodes.
59195919
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
59205920
public:
5921-
DependentDecltypeType(Expr *E, QualType UnderlyingTpe);
5921+
DependentDecltypeType(Expr *E);
59225922

59235923
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
59245924
Profile(ID, Context, getUnderlyingExpr());

clang/lib/AST/ASTContext.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6355,34 +6355,36 @@ QualType ASTContext::getReferenceQualifiedType(const Expr *E) const {
63556355
/// nodes. This would never be helpful, since each such type has its own
63566356
/// expression, and would not give a significant memory saving, since there
63576357
/// is an Expr tree under each such type.
6358-
QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
6359-
DecltypeType *dt;
6360-
6358+
QualType ASTContext::getDecltypeType(Expr *E, QualType UnderlyingType) const {
63616359
// C++11 [temp.type]p2:
63626360
// If an expression e involves a template parameter, decltype(e) denotes a
63636361
// unique dependent type. Two such decltype-specifiers refer to the same
63646362
// type only if their expressions are equivalent (14.5.6.1).
6365-
if (e->isInstantiationDependent()) {
6363+
QualType CanonType;
6364+
if (!E->isInstantiationDependent()) {
6365+
CanonType = getCanonicalType(UnderlyingType);
6366+
} else if (!UnderlyingType.isNull()) {
6367+
CanonType = getDecltypeType(E, QualType());
6368+
} else {
63666369
llvm::FoldingSetNodeID ID;
6367-
DependentDecltypeType::Profile(ID, *this, e);
6370+
DependentDecltypeType::Profile(ID, *this, E);
63686371

63696372
void *InsertPos = nullptr;
6370-
DependentDecltypeType *Canon
6371-
= DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
6372-
if (!Canon) {
6373-
// Build a new, canonical decltype(expr) type.
6374-
Canon = new (*this, alignof(DependentDecltypeType))
6375-
DependentDecltypeType(e, DependentTy);
6376-
DependentDecltypeTypes.InsertNode(Canon, InsertPos);
6377-
}
6378-
dt = new (*this, alignof(DecltypeType))
6379-
DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
6380-
} else {
6381-
dt = new (*this, alignof(DecltypeType))
6382-
DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
6383-
}
6384-
Types.push_back(dt);
6385-
return QualType(dt, 0);
6373+
if (DependentDecltypeType *Canon =
6374+
DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos))
6375+
return QualType(Canon, 0);
6376+
6377+
// Build a new, canonical decltype(expr) type.
6378+
auto *DT =
6379+
new (*this, alignof(DependentDecltypeType)) DependentDecltypeType(E);
6380+
DependentDecltypeTypes.InsertNode(DT, InsertPos);
6381+
Types.push_back(DT);
6382+
return QualType(DT, 0);
6383+
}
6384+
auto *DT = new (*this, alignof(DecltypeType))
6385+
DecltypeType(E, UnderlyingType, CanonType);
6386+
Types.push_back(DT);
6387+
return QualType(DT, 0);
63866388
}
63876389

63886390
QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,

clang/lib/AST/Type.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4055,8 +4055,8 @@ QualType DecltypeType::desugar() const {
40554055
return QualType(this, 0);
40564056
}
40574057

4058-
DependentDecltypeType::DependentDecltypeType(Expr *E, QualType UnderlyingType)
4059-
: DecltypeType(E, UnderlyingType) {}
4058+
DependentDecltypeType::DependentDecltypeType(Expr *E)
4059+
: DecltypeType(E, QualType()) {}
40604060

40614061
void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
40624062
const ASTContext &Context, Expr *E) {

0 commit comments

Comments
 (0)