diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 23 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 8 |
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) {} |