diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-31 03:54:25 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-31 03:54:25 +0000 |
commit | 2ec09f1dc123e1942ed756e8ee4fef86451eac9e (patch) | |
tree | 9f72b9fbba13c5812220255c234ead5577a59b72 | |
parent | 7b1fdbda2757cc4a7f25664475be44119d7f8e59 (diff) |
Canonicalize dependent extended vector types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77663 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 2 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 19 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 34 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 8 | ||||
-rw-r--r-- | test/SemaTemplate/canonical-expr-type.cpp | 12 |
5 files changed, 64 insertions, 11 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 1c64f0be05..abbcb44377 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -71,7 +71,7 @@ class ASTContext { llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes; std::vector<VariableArrayType*> VariableArrayTypes; llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes; - std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes; + llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes; llvm::FoldingSet<VectorType> VectorTypes; llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 411a279cd0..7bf877ed1a 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1235,21 +1235,23 @@ public: /// typedef T __attribute__((ext_vector_type(Size))) type; /// } /// @endcode -class DependentSizedExtVectorType : public Type { +class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { + ASTContext &Context; Expr *SizeExpr; /// ElementType - The element type of the array. QualType ElementType; SourceLocation loc; - DependentSizedExtVectorType(QualType ElementType, QualType can, - Expr *SizeExpr, SourceLocation loc) + DependentSizedExtVectorType(ASTContext &Context, QualType ElementType, + QualType can, Expr *SizeExpr, SourceLocation loc) : Type (DependentSizedExtVector, can, true), - SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {} + Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), + loc(loc) {} friend class ASTContext; virtual void Destroy(ASTContext& C); public: - const Expr *getSizeExpr() const { return SizeExpr; } + Expr *getSizeExpr() const { return SizeExpr; } QualType getElementType() const { return ElementType; } SourceLocation getAttributeLoc() const { return loc; } @@ -1260,6 +1262,13 @@ public: return T->getTypeClass() == DependentSizedExtVector; } static bool classof(const DependentSizedExtVectorType *) { return true; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, getElementType(), getSizeExpr()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, + QualType ElementType, Expr *SizeExpr); }; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 912b302f74..1b73679beb 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1515,11 +1515,35 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, Expr *SizeExpr, SourceLocation AttrLoc) { - DependentSizedExtVectorType *New = - new (*this,8) DependentSizedExtVectorType(vecType, QualType(), - SizeExpr, AttrLoc); - - DependentSizedExtVectorTypes.push_back(New); + llvm::FoldingSetNodeID ID; + DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType), + SizeExpr); + + void *InsertPos = 0; + DependentSizedExtVectorType *Canon + = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); + DependentSizedExtVectorType *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) DependentSizedExtVectorType(*this, vecType, + QualType(Canon, 0), + SizeExpr, AttrLoc); + } else { + QualType CanonVecTy = getCanonicalType(vecType); + if (CanonVecTy == vecType) { + New = new (*this,8) DependentSizedExtVectorType(*this, vecType, + QualType(), SizeExpr, + AttrLoc); + DependentSizedExtVectorTypes.InsertNode(New, InsertPos); + } else { + QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr, + SourceLocation()); + New = new (*this,8) DependentSizedExtVectorType(*this, vecType, Canon, + SizeExpr, AttrLoc); + } + } + Types.push_back(New); return QualType(New, 0); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index ed91e80c3e..bf506415ac 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -76,6 +76,14 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, E->Profile(ID, Context, true); } +void +DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, + ASTContext &Context, + QualType ElementType, Expr *SizeExpr) { + ID.AddPointer(ElementType.getAsOpaquePtr()); + SizeExpr->Profile(ID, Context, true); +} + void DependentSizedExtVectorType::Destroy(ASTContext& C) { // FIXME: Deallocate size expression, once we're cloning properly. // if (SizeExpr) diff --git a/test/SemaTemplate/canonical-expr-type.cpp b/test/SemaTemplate/canonical-expr-type.cpp index 767e0055d8..48147f0e4c 100644 --- a/test/SemaTemplate/canonical-expr-type.cpp +++ b/test/SemaTemplate/canonical-expr-type.cpp @@ -24,3 +24,15 @@ void f1(T (&array)[M + N]) { } template<typename T, int M, int N> void f1(T (&array)[M + N]) { } // expected-error{{redefinition}} + +// Test dependently-sized extended vector type canonicalization +template<typename T, int N, int M> +struct X2 { + typedef T __attribute__((ext_vector_type(N))) type1; + typedef T __attribute__((ext_vector_type(M))) type2; + typedef T __attribute__((ext_vector_type(N))) type3; + + void f0(type1); // expected-note{{previous}} + void f0(type2); + void f0(type3); // expected-error{{redeclared}} +}; |