forked from OSchip/llvm-project
Canonicalization of dependent C++0x decltype types.
llvm-svn: 77643
This commit is contained in:
parent
5811ab5cf3
commit
a21f6c3c71
|
@ -76,12 +76,14 @@ class ASTContext {
|
|||
llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
|
||||
llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
|
||||
llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
|
||||
llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
|
||||
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
|
||||
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
|
||||
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
|
||||
llvm::FoldingSet<TypenameType> TypenameTypes;
|
||||
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
|
||||
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
|
||||
|
||||
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
|
||||
|
|
|
@ -1636,6 +1636,7 @@ class DecltypeType : public Type {
|
|||
// from it.
|
||||
QualType UnderlyingType;
|
||||
|
||||
protected:
|
||||
DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
|
@ -1649,6 +1650,22 @@ public:
|
|||
static bool classof(const DecltypeType *) { return true; }
|
||||
};
|
||||
|
||||
/// Subclass of DecltypeType that is used for canonical, dependent
|
||||
/// C++0x decltype types.
|
||||
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
|
||||
ASTContext &Context;
|
||||
|
||||
public:
|
||||
DependentDecltypeType(ASTContext &Context, Expr *E);
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, Context, getUnderlyingExpr());
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
|
||||
Expr *E);
|
||||
};
|
||||
|
||||
class TagType : public Type {
|
||||
/// Stores the TagDecl associated with this type. The decl will
|
||||
/// point to the TagDecl that actually defines the entity (or is a
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
|
||||
|
||||
void f();
|
||||
|
||||
// FIXME: would like to refer to the first function parameter in these test,
|
||||
// but that won't work (yet).
|
||||
|
||||
// Test typeof(expr) canonicalization
|
||||
template<typename T, T N>
|
||||
void f0(T x, decltype(f(N)) y) { } // expected-note{{previous}}
|
||||
|
||||
template<typename T, T N>
|
||||
void f0(T x, decltype((f)(N)) y) { }
|
||||
|
||||
template<typename U, U M>
|
||||
void f0(U u, decltype(f(M))) { } // expected-error{{redefinition}}
|
Loading…
Reference in New Issue