Canonicalize dependent extended vector types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77663 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-07-31 03:54:25 +00:00
Родитель 7b1fdbda27
Коммит 2ec09f1dc1
5 изменённых файлов: 64 добавлений и 11 удалений

Просмотреть файл

@ -71,7 +71,7 @@ class ASTContext {
llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes; llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
std::vector<VariableArrayType*> VariableArrayTypes; std::vector<VariableArrayType*> VariableArrayTypes;
llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes; llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes; llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes;
llvm::FoldingSet<VectorType> VectorTypes; llvm::FoldingSet<VectorType> VectorTypes;
llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes; llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;

Просмотреть файл

@ -1235,21 +1235,23 @@ public:
/// typedef T __attribute__((ext_vector_type(Size))) type; /// typedef T __attribute__((ext_vector_type(Size))) type;
/// } /// }
/// @endcode /// @endcode
class DependentSizedExtVectorType : public Type { class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
ASTContext &Context;
Expr *SizeExpr; Expr *SizeExpr;
/// ElementType - The element type of the array. /// ElementType - The element type of the array.
QualType ElementType; QualType ElementType;
SourceLocation loc; SourceLocation loc;
DependentSizedExtVectorType(QualType ElementType, QualType can, DependentSizedExtVectorType(ASTContext &Context, QualType ElementType,
Expr *SizeExpr, SourceLocation loc) QualType can, Expr *SizeExpr, SourceLocation loc)
: Type (DependentSizedExtVector, can, true), : Type (DependentSizedExtVector, can, true),
SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {} Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
loc(loc) {}
friend class ASTContext; friend class ASTContext;
virtual void Destroy(ASTContext& C); virtual void Destroy(ASTContext& C);
public: public:
const Expr *getSizeExpr() const { return SizeExpr; } Expr *getSizeExpr() const { return SizeExpr; }
QualType getElementType() const { return ElementType; } QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return loc; } SourceLocation getAttributeLoc() const { return loc; }
@ -1260,6 +1262,13 @@ public:
return T->getTypeClass() == DependentSizedExtVector; return T->getTypeClass() == DependentSizedExtVector;
} }
static bool classof(const DependentSizedExtVectorType *) { return true; } 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);
}; };

Просмотреть файл

@ -1515,11 +1515,35 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
Expr *SizeExpr, Expr *SizeExpr,
SourceLocation AttrLoc) { SourceLocation AttrLoc) {
DependentSizedExtVectorType *New = llvm::FoldingSetNodeID ID;
new (*this,8) DependentSizedExtVectorType(vecType, QualType(), DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
SizeExpr, AttrLoc); SizeExpr);
DependentSizedExtVectorTypes.push_back(New); 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); Types.push_back(New);
return QualType(New, 0); return QualType(New, 0);
} }

Просмотреть файл

@ -76,6 +76,14 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
E->Profile(ID, Context, true); 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) { void DependentSizedExtVectorType::Destroy(ASTContext& C) {
// FIXME: Deallocate size expression, once we're cloning properly. // FIXME: Deallocate size expression, once we're cloning properly.
// if (SizeExpr) // if (SizeExpr)

Просмотреть файл

@ -24,3 +24,15 @@ void f1(T (&array)[M + N]) { }
template<typename T, int M, int N> template<typename T, int M, int N>
void f1(T (&array)[M + N]) { } // expected-error{{redefinition}} 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}}
};