aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclTemplate.h21
-rw-r--r--lib/AST/DeclBase.cpp4
-rw-r--r--lib/AST/DeclTemplate.cpp47
-rw-r--r--lib/Sema/SemaTemplate.cpp7
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp8
-rw-r--r--test/SemaTemplate/issue150.cpp58
7 files changed, 131 insertions, 19 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 28021564cb..9c20969c1f 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -844,13 +844,16 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- /// Create a template function node.
+ /// \brief Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
+ /// \brief Create an empty function template node.
+ static FunctionTemplateDecl *Create(ASTContext &C, EmptyShell);
+
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionTemplateDecl *D) { return true; }
@@ -1556,14 +1559,7 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
- unsigned SequenceNumber)
- : ClassTemplateSpecializationDecl(Context,
- ClassTemplatePartialSpecialization,
- TK, DC, L, SpecializedTemplate,
- Args, NumArgs, PrevDecl),
- TemplateParams(Params), ArgsAsWritten(ArgInfos),
- NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
- InstantiatedFromMember(0, false) { }
+ unsigned SequenceNumber);
ClassTemplatePartialSpecializationDecl()
: ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
@@ -1746,6 +1742,10 @@ protected:
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
+ ClassTemplateDecl(EmptyShell Empty)
+ : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
+ DeclarationName(), 0, 0) { }
+
CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
@@ -1772,6 +1772,9 @@ public:
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl);
+ /// Create an empty class template node.
+ static ClassTemplateDecl *Create(ASTContext &C, EmptyShell);
+
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
ClassTemplateSpecializationDecl *
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 81df00d6c7..0642f423c6 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -960,7 +960,7 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
- if (isa<ClassTemplateSpecializationDecl>(D))
+ if (isa<ClassTemplateSpecializationDecl>(D) || D->isTemplateParameter())
return;
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
if (FD->isFunctionTemplateSpecialization())
@@ -999,7 +999,7 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
- if (isa<ClassTemplateSpecializationDecl>(D))
+ if (isa<ClassTemplateSpecializationDecl>(D) || D->isTemplateParameter())
return;
ASTContext *C = 0;
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 0554cfca3a..266d913ff4 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -165,9 +165,20 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl) {
+ // Take ownership of the template parameters.
+ for (TemplateParameterList::iterator P = Params->begin(),
+ PEnd = Params->end();
+ P != PEnd; ++P)
+ (*P)->setDeclContext(cast<DeclContext>(Decl));
+
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
+FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, EmptyShell) {
+ return new (C) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
+ 0, 0);
+}
+
RedeclarableTemplateDecl::CommonBase *
FunctionTemplateDecl::newCommon(ASTContext &C) {
Common *CommonPtr = new (C) Common;
@@ -196,11 +207,21 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
TemplateParameterList *Params,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl) {
+ // Take ownership of the template parameters.
+ for (TemplateParameterList::iterator P = Params->begin(),
+ PEnd = Params->end();
+ P != PEnd; ++P)
+ (*P)->setDeclContext(cast<DeclContext>(Decl));
+
ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
New->setPreviousDeclaration(PrevDecl);
return New;
}
+ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, EmptyShell Empty) {
+ return new (C) ClassTemplateDecl(Empty);
+}
+
void ClassTemplateDecl::LoadLazySpecializations() {
Common *CommonPtr = getCommonPtr();
if (CommonPtr->LazySpecializations) {
@@ -593,6 +614,32 @@ ClassTemplateSpecializationDecl::getSourceRange() const {
//===----------------------------------------------------------------------===//
// ClassTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
+ClassTemplatePartialSpecializationDecl::
+ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
+ DeclContext *DC, SourceLocation L,
+ TemplateParameterList *Params,
+ ClassTemplateDecl *SpecializedTemplate,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber)
+ : ClassTemplateSpecializationDecl(Context,
+ ClassTemplatePartialSpecialization,
+ TK, DC, L, SpecializedTemplate,
+ Args, NumArgs, PrevDecl),
+ TemplateParams(Params), ArgsAsWritten(ArgInfos),
+ NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+ InstantiatedFromMember(0, false)
+{
+ // Take ownership of the template parameters.
+ for (TemplateParameterList::iterator P = Params->begin(),
+ PEnd = Params->end();
+ P != PEnd; ++P)
+ (*P)->setDeclContext(this);
+}
+
ClassTemplatePartialSpecializationDecl *
ClassTemplatePartialSpecializationDecl::
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 9b0d2611ce..f70efc1c8e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -527,6 +527,7 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
= TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
Loc, Depth, Position, ParamName, Typename,
Ellipsis);
+ Param->setAccess(AS_public);
if (Invalid)
Param->setInvalidDecl();
@@ -652,6 +653,8 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
D.getIdentifierLoc(),
Depth, Position, ParamName, T,
IsParameterPack, TInfo);
+ Param->setAccess(AS_public);
+
if (Invalid)
Param->setInvalidDecl();
@@ -705,13 +708,13 @@ Decl *Sema::ActOnTemplateTemplateParameter(Scope* S,
// Construct the parameter object.
bool IsParameterPack = EllipsisLoc.isValid();
- // FIXME: Pack-ness is dropped
TemplateTemplateParmDecl *Param =
TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
NameLoc.isInvalid()? TmpLoc : NameLoc,
Depth, Position, IsParameterPack,
Name, Params);
-
+ Param->setAccess(AS_public);
+
// If the template template parameter has a name, then link the identifier
// into the scope and lookup mechanisms.
if (Name) {
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index cbbc2d9f89..01c88057ea 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1447,7 +1447,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
TTPT->getIndex(), D->getIdentifier(),
D->wasDeclaredWithTypename(),
D->isParameterPack());
-
+ Inst->setAccess(AS_public);
+
if (D->hasDefaultArgument())
Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false);
@@ -1595,6 +1596,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
D->getIdentifier(), T,
D->isParameterPack(), DI);
+ Param->setAccess(AS_public);
if (Invalid)
Param->setInvalidDecl();
@@ -1628,6 +1630,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
D->getPosition(), D->isParameterPack(),
D->getIdentifier(), InstParams);
Param->setDefaultArgument(D->getDefaultArgument(), false);
+ Param->setAccess(AS_public);
// Introduce this template parameter's instantiation into the instantiation
// scope.
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 046d901407..1e4ff83d5f 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1485,19 +1485,17 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
D = FriendTemplateDecl::Create(*Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE:
- D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(),
- DeclarationName(), 0, 0, 0);
+ D = ClassTemplateDecl::Create(*Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE_SPECIALIZATION:
D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
D = ClassTemplatePartialSpecializationDecl::Create(*Context,
- Decl::EmptyShell());
+ Decl::EmptyShell());
break;
case DECL_FUNCTION_TEMPLATE:
- D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(),
- DeclarationName(), 0, 0);
+ D = FunctionTemplateDecl::Create(*Context, Decl::EmptyShell());
break;
case DECL_TEMPLATE_TYPE_PARM:
D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell());
diff --git a/test/SemaTemplate/issue150.cpp b/test/SemaTemplate/issue150.cpp
index 647df2cc0b..0d7930723f 100644
--- a/test/SemaTemplate/issue150.cpp
+++ b/test/SemaTemplate/issue150.cpp
@@ -2,6 +2,16 @@
// Core issue 150: Template template parameters and default arguments
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
namespace PR9353 {
template<class _T, class Traits> class IM;
@@ -11,3 +21,51 @@ namespace PR9353 {
void f(IM<int, int>* m) { foo(m); }
}
+
+namespace PR9400 {
+ template<template <typename T, typename = T > class U> struct A
+ {
+ template<int> U<int> foo();
+ };
+
+ template <typename T, typename = T>
+ struct s {
+ };
+
+ void f() {
+ A<s> x;
+ x.foo<2>();
+ }
+}
+
+namespace MultiReplace {
+ template<typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X {
+ typedef TT<Z> type;
+ };
+
+ template<typename T, typename = int, typename = float>
+ struct Y { };
+
+ int check0[is_same<X<int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
+}
+
+namespace MultiReplacePartial {
+ template<typename First, typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X {
+ typedef TT<Z> type;
+ };
+
+ template<typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X<int, Z, TT> {
+ typedef TT<Z> type;
+ };
+
+ template<typename T, typename = int, typename = float>
+ struct Y { };
+
+ int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
+}