diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-04 17:52:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-04 17:52:15 +0000 |
commit | 9a299e0575ce235f491014627c7267e2d2cd73de (patch) | |
tree | f20b04ee02ae3e9fa9a8a14e2b26b0a6c4f7205a /lib | |
parent | abfb4059e5c4c5ce35649f328d6917b1b6c1ba9c (diff) |
Make sure to put template parameters into their owning template's
DeclContext once we've created it. This mirrors what we do for
function parameters, where the parameters start out with
translation-unit context and then are adopted by the appropriate
DeclContext when it is created. Also give template parameters public
access and make sure that they don't show up for the purposes of name
lookup.
Fixes PR9400, a regression introduced by r126920, which implemented
substitution of default template arguments provided in template
template parameters (C++ core issue 150).
How on earth could the DeclContext of a template parameter affect the
handling of default template arguments?
I'm so glad you asked! The link is
Sema::getTemplateInstantiationArgs(), which determines the outer
template argument lists that correspond to a given declaration. When
we're instantiating a default template argument for a template
template parameter within the body of a template definition (not it's
instantiation, per core issue 150), we weren't getting any outer
template arguments because the context of the template template
parameter was the translation unit. Now that the context of the
template template parameter is its owning template, we get the
template arguments from the injected-class-name of the owning
template, so substitution works as it should.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127004 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 47 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 8 |
5 files changed, 61 insertions, 10 deletions
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()); |