diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 42 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 12 |
2 files changed, 44 insertions, 10 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f47e28b8f2..51815d5f31 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1371,8 +1371,7 @@ QualType ASTContext::getVariableArrayType(QualType EltTy, /// getDependentSizedArrayType - Returns a non-unique reference to /// the type for a dependently-sized array of the specified element -/// type. FIXME: We will need these to be uniqued, or at least -/// comparable, at some point. +/// type. QualType ASTContext::getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, @@ -1381,15 +1380,38 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy, assert((NumElts->isTypeDependent() || NumElts->isValueDependent()) && "Size must be type- or value-dependent!"); - // Since we don't unique expressions, it isn't possible to unique - // dependently-sized array types. - - DependentSizedArrayType *New = - new (*this,8) DependentSizedArrayType(EltTy, QualType(), - NumElts, ASM, EltTypeQuals, - Brackets); + llvm::FoldingSetNodeID ID; + DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM, + EltTypeQuals, NumElts); - DependentSizedArrayTypes.push_back(New); + void *InsertPos = 0; + DependentSizedArrayType *Canon + = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos); + DependentSizedArrayType *New; + if (Canon) { + // We already have a canonical version of this array type; use it as + // the canonical type for a newly-built type. + New = new (*this,8) DependentSizedArrayType(*this, EltTy, + QualType(Canon, 0), + NumElts, ASM, EltTypeQuals, + Brackets); + } else { + QualType CanonEltTy = getCanonicalType(EltTy); + if (CanonEltTy == EltTy) { + New = new (*this,8) DependentSizedArrayType(*this, EltTy, QualType(), + NumElts, ASM, EltTypeQuals, + Brackets); + DependentSizedArrayTypes.InsertNode(New, InsertPos); + } else { + QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts, + ASM, EltTypeQuals, + SourceRange()); + New = new (*this,8) DependentSizedArrayType(*this, EltTy, Canon, + NumElts, ASM, EltTypeQuals, + Brackets); + } + } + Types.push_back(New); return QualType(New, 0); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index c8e317c7d3..ed91e80c3e 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -64,6 +64,18 @@ void DependentSizedArrayType::Destroy(ASTContext& C) { C.Deallocate(this); } +void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, + ASTContext &Context, + QualType ET, + ArraySizeModifier SizeMod, + unsigned TypeQuals, + Expr *E) { + ID.AddPointer(ET.getAsOpaquePtr()); + ID.AddInteger(SizeMod); + ID.AddInteger(TypeQuals); + E->Profile(ID, Context, true); +} + void DependentSizedExtVectorType::Destroy(ASTContext& C) { // FIXME: Deallocate size expression, once we're cloning properly. // if (SizeExpr) |