aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp23
-rw-r--r--lib/AST/Type.cpp8
2 files changed, 28 insertions, 3 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 81cab925eb..f47e28b8f2 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1954,9 +1954,26 @@ static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
/// on canonical type's (which are always unique).
QualType ASTContext::getDecltypeType(Expr *e) {
DecltypeType *dt;
- if (e->isTypeDependent()) // FIXME: canonicalize the expression
- dt = new (*this, 8) DecltypeType(e, DependentTy);
- else {
+ if (e->isTypeDependent()) {
+ llvm::FoldingSetNodeID ID;
+ DependentDecltypeType::Profile(ID, *this, e);
+
+ void *InsertPos = 0;
+ DependentDecltypeType *Canon
+ = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (Canon) {
+ // We already have a "canonical" version of an equivalent, dependent
+ // decltype type. Use that as our canonical type.
+ dt = new (*this, 8) DecltypeType(e, DependentTy,
+ QualType((DecltypeType*)Canon, 0));
+ }
+ else {
+ // Build a new, canonical typeof(expr) type.
+ Canon = new (*this, 8) DependentDecltypeType(*this, e);
+ DependentDecltypeTypes.InsertNode(Canon, InsertPos);
+ dt = Canon;
+ }
+ } else {
QualType T = getDecltypeForExpr(e, *this);
dt = new (*this, 8) DecltypeType(e, T, getCanonicalType(T));
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 76d35465fe..c8e317c7d3 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -968,6 +968,14 @@ DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
UnderlyingType(underlyingType) {
}
+DependentDecltypeType::DependentDecltypeType(ASTContext &Context, Expr *E)
+ : DecltypeType(E, Context.DependentTy), Context(Context) { }
+
+void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context, Expr *E) {
+ E->Profile(ID, Context, true);
+}
+
TagType::TagType(TypeClass TC, TagDecl *D, QualType can)
: Type(TC, can, D->isDependentType()), decl(D, 0) {}