зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
7b1fdbda27
Коммит
2ec09f1dc1
|
@ -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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DependentSizedExtVectorTypes.push_back(New);
|
|
||||||
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}}
|
||||||
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче