summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-29 16:09:57 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-29 16:09:57 +0000
commit0004417e81d881bffd7190ae6fd2ce3553363b3b (patch)
treedde1931f65e8eb0d706ecc89b3ecf268b45f723a /clang
parentea2f1ceb4b6d5f7552379f4e2ea6efb0b12f195c (diff)
downloadbcm5719-llvm-0004417e81d881bffd7190ae6fd2ce3553363b3b.tar.gz
bcm5719-llvm-0004417e81d881bffd7190ae6fd2ce3553363b3b.zip
Use the new statement/expression profiling code to unique dependent
template arguments, as in template specialization types. This permits matching out-of-line definitions of members for class templates that involve non-type template parameters. llvm-svn: 77462
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclTemplate.h23
-rw-r--r--clang/include/clang/AST/Type.h13
-rw-r--r--clang/lib/AST/ASTContext.cpp7
-rw-r--r--clang/lib/AST/StmtProfile.cpp13
-rw-r--r--clang/lib/AST/Type.cpp9
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp12
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp1
-rw-r--r--clang/test/SemaTemplate/injected-class-name.cpp10
9 files changed, 63 insertions, 28 deletions
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 86016209313..17c8bc877d0 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -315,7 +315,7 @@ public:
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
/// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID) const {
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const {
ID.AddInteger(Kind);
switch (Kind) {
case Null:
@@ -326,7 +326,7 @@ public:
break;
case Declaration:
- ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
+ ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
break;
case Integral:
@@ -335,14 +335,13 @@ public:
break;
case Expression:
- // FIXME: We need a canonical representation of expressions.
- ID.AddPointer(getAsExpr());
+ getAsExpr()->Profile(ID, Context, true);
break;
case Pack:
ID.AddInteger(Args.NumArgs);
for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I].Profile(ID);
+ Args.Args[I].Profile(ID, Context);
}
}
};
@@ -534,15 +533,16 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, TemplateArguments->getFlatArgumentList(),
- TemplateArguments->flat_size());
+ TemplateArguments->flat_size(),
+ Function->getASTContext());
}
static void
Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
+ unsigned NumTemplateArgs, ASTContext &Context) {
ID.AddInteger(NumTemplateArgs);
for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
- TemplateArgs[Arg].Profile(ID);
+ TemplateArgs[Arg].Profile(ID, Context);
}
};
@@ -918,15 +918,16 @@ public:
}
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size());
+ Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
+ getASTContext());
}
static void
Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
+ unsigned NumTemplateArgs, ASTContext &Context) {
ID.AddInteger(NumTemplateArgs);
for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
- TemplateArgs[Arg].Profile(ID);
+ TemplateArgs[Arg].Profile(ID, Context);
}
static bool classof(const Decl *D) {
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index be018026e36..66d23f3eb56 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1782,14 +1782,18 @@ public:
class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
- /// \brief The name of the template being specialized.
+ // FIXME: Currently needed for profiling expressions; can we avoid this?
+ ASTContext &Context;
+
+ /// \brief The name of the template being specialized.
TemplateName Template;
/// \brief - The number of template arguments named in this class
/// template specialization.
unsigned NumArgs;
- TemplateSpecializationType(TemplateName T,
+ TemplateSpecializationType(ASTContext &Context,
+ TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs, QualType Canon);
@@ -1833,11 +1837,12 @@ public:
const PrintingPolicy &Policy) const;
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Template, getArgs(), NumArgs);
+ Profile(ID, Template, getArgs(), NumArgs, Context);
}
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- const TemplateArgument *Args, unsigned NumArgs);
+ const TemplateArgument *Args, unsigned NumArgs,
+ ASTContext &Context);
static bool classof(const Type *T) {
return T->getTypeClass() == TemplateSpecialization;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 931010d9046..f3a417181e7 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1682,7 +1682,7 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
// exists.
llvm::FoldingSetNodeID ID;
TemplateSpecializationType::Profile(ID, CanonTemplate,
- CanonArgs.data(), NumArgs);
+ CanonArgs.data(), NumArgs, *this);
void *InsertPos = 0;
TemplateSpecializationType *Spec
@@ -1693,7 +1693,7 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
void *Mem = Allocate((sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs),
8);
- Spec = new (Mem) TemplateSpecializationType(CanonTemplate,
+ Spec = new (Mem) TemplateSpecializationType(*this, CanonTemplate,
CanonArgs.data(), NumArgs,
QualType());
Types.push_back(Spec);
@@ -1713,7 +1713,8 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
sizeof(TemplateArgument) * NumArgs),
8);
TemplateSpecializationType *Spec
- = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, Canon);
+ = new (Mem) TemplateSpecializationType(*this, Template, Args, NumArgs,
+ Canon);
Types.push_back(Spec);
return QualType(Spec, 0);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 0f241c20ab2..688777d4aac 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -107,6 +107,10 @@ void StmtProfiler::VisitIfStmt(IfStmt *S) {
VisitStmt(S);
}
+void StmtProfiler::VisitSwitchStmt(SwitchStmt *S) {
+ VisitStmt(S);
+}
+
void StmtProfiler::VisitWhileStmt(WhileStmt *S) {
VisitStmt(S);
}
@@ -330,6 +334,10 @@ void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) {
VisitExpr(S);
}
+void StmtProfiler::VisitVAArgExpr(VAArgExpr *S) {
+ VisitExpr(S);
+}
+
void StmtProfiler::VisitInitListExpr(InitListExpr *S) {
if (S->getSyntacticForm()) {
VisitInitListExpr(S->getSyntacticForm());
@@ -416,6 +424,10 @@ void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
ID.AddBoolean(S->getValue());
}
+void StmtProfiler::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
+ VisitExpr(S);
+}
+
void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
VisitExpr(S);
if (S->isTypeOperand())
@@ -595,6 +607,7 @@ void StmtProfiler::VisitDecl(Decl *D) {
= dyn_cast_or_null<NonTypeTemplateParmDecl>(D)) {
ID.AddInteger(NTTP->getDepth());
ID.AddInteger(NTTP->getIndex());
+ VisitType(NTTP->getType());
return;
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 04961ed0fcb..f937d15ffb9 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1033,11 +1033,13 @@ anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
}
TemplateSpecializationType::
-TemplateSpecializationType(TemplateName T, const TemplateArgument *Args,
+TemplateSpecializationType(ASTContext &Context, TemplateName T,
+ const TemplateArgument *Args,
unsigned NumArgs, QualType Canon)
: Type(TemplateSpecialization,
Canon.isNull()? QualType(this, 0) : Canon,
T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
+ Context(Context),
Template(T), NumArgs(NumArgs)
{
assert((!Canon.isNull() ||
@@ -1074,10 +1076,11 @@ void
TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
TemplateName T,
const TemplateArgument *Args,
- unsigned NumArgs) {
+ unsigned NumArgs,
+ ASTContext &Context) {
T.Profile(ID);
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
- Args[Idx].Profile(ID);
+ Args[Idx].Profile(ID, Context);
}
const Type *QualifierSet::strip(const Type* T) {
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 97812046f7f..f27d551d102 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -930,7 +930,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
llvm::FoldingSetNodeID ID;
ClassTemplateSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.flatSize(),
+ Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
@@ -2433,12 +2434,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
// FIXME: Template parameter list matters, too
ClassTemplatePartialSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.flatSize(),
+ Context);
}
else
ClassTemplateSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.flatSize(),
+ Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl = 0;
@@ -2703,7 +2706,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
llvm::FoldingSetNodeID ID;
ClassTemplateSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.flatSize(),
+ Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b04b63523df..6506cde2af8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -321,7 +321,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {
llvm::FoldingSetNodeID ID;
FunctionTemplateSpecializationInfo::Profile(ID,
TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size());
+ TemplateArgs.flat_size(),
+ SemaRef.Context);
FunctionTemplateSpecializationInfo *Info
= FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
index 7606a2a6eef..2571e45c5cd 100644
--- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
template<int N, int M>
struct A0 {
diff --git a/clang/test/SemaTemplate/injected-class-name.cpp b/clang/test/SemaTemplate/injected-class-name.cpp
index c5f826d849c..f9674c39a58 100644
--- a/clang/test/SemaTemplate/injected-class-name.cpp
+++ b/clang/test/SemaTemplate/injected-class-name.cpp
@@ -19,7 +19,7 @@ X<float>::X<int> xi = x;
// [temp.local]p1:
-// FIXME: test non-type and template template parameters
+// FIXME: test template template parameters
template<typename T, typename U>
struct X0 {
typedef T type;
@@ -38,3 +38,11 @@ struct X0 {
void f2(X0&);
void f2(const ::X0<type, U_type2>&); // expected-error{{redecl}}
};
+
+template<typename T, T N>
+struct X1 {
+ void f0(const X1&); // expected-note{{here}}
+ void f0(X1&);
+ void f0(const X1<T, N>&); // expected-error{{redecl}}
+};
+
OpenPOWER on IntegriCloud