[cfe-commits] r77643 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp test/SemaTemplate/canonical-expr-type-0x.cpp
Douglas Gregor
dgregor at apple.com
Thu Jul 30 16:36:40 PDT 2009
Author: dgregor
Date: Thu Jul 30 18:36:40 2009
New Revision: 77643
URL: http://llvm.org/viewvc/llvm-project?rev=77643&view=rev
Log:
Canonicalization of dependent C++0x decltype types.
Added:
cfe/trunk/test/SemaTemplate/canonical-expr-type-0x.cpp
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=77643&r1=77642&r2=77643&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jul 30 18:36:40 2009
@@ -76,12 +76,14 @@
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;
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=77643&r1=77642&r2=77643&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jul 30 18:36:40 2009
@@ -1636,6 +1636,7 @@
// from it.
QualType UnderlyingType;
+protected:
DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
friend class ASTContext; // ASTContext creates these.
public:
@@ -1649,6 +1650,22 @@
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
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=77643&r1=77642&r2=77643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jul 30 18:36:40 2009
@@ -1954,9 +1954,26 @@
/// 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));
}
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=77643&r1=77642&r2=77643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jul 30 18:36:40 2009
@@ -968,6 +968,14 @@
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) {}
Added: cfe/trunk/test/SemaTemplate/canonical-expr-type-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/canonical-expr-type-0x.cpp?rev=77643&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/canonical-expr-type-0x.cpp (added)
+++ cfe/trunk/test/SemaTemplate/canonical-expr-type-0x.cpp Thu Jul 30 18:36:40 2009
@@ -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}}
\ No newline at end of file
More information about the cfe-commits
mailing list