diff options
author | Hans Wennborg <hans@hanshq.net> | 2014-05-02 02:01:07 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2014-05-02 02:01:07 +0000 |
commit | b6d4e8cd4ee065166d4732e271abbc06a74dbdb2 (patch) | |
tree | 9fa09c4f0bb722385cdd336c596c8848923010de /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | db2fc6d75614db2691ee61c442f42cf691b89522 (diff) | |
download | bcm5719-llvm-b6d4e8cd4ee065166d4732e271abbc06a74dbdb2.tar.gz bcm5719-llvm-b6d4e8cd4ee065166d4732e271abbc06a74dbdb2.zip |
Handle -fdelayed-template-parsing of out-of-line definitions of
class template member classes (PR19613)
Also improve this code in general by implementing suggestions
from Richard.
Differential Revision: http://reviews.llvm.org/D3555?id=9020
llvm-svn: 207822
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6416b6277c6..1feb979f69f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5980,47 +5980,55 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { } } -void Sema::ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D) { +unsigned Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { if (!D) - return; + return 0; - int NumParamList = D->getNumTemplateParameterLists(); - for (int i = 0; i < NumParamList; i++) { - TemplateParameterList* Params = D->getTemplateParameterList(i); - for (TemplateParameterList::iterator Param = Params->begin(), - ParamEnd = Params->end(); - Param != ParamEnd; ++Param) { - NamedDecl *Named = cast<NamedDecl>(*Param); - if (Named->getDeclName()) { - S->AddDecl(Named); - IdResolver.AddDecl(Named); - } + // The order of template parameters is not important here. All names + // get added to the same scope. + SmallVector<TemplateParameterList *, 4> ParameterLists; + + if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) + D = TD->getTemplatedDecl(); + + if (auto *PSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) + ParameterLists.push_back(PSD->getTemplateParameters()); + + if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { + for (unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i) + ParameterLists.push_back(DD->getTemplateParameterList(i)); + + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) + ParameterLists.push_back(FTD->getTemplateParameters()); } } -} -void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { - if (!D) - return; - - TemplateParameterList *Params = 0; - if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) - Params = Template->getTemplateParameters(); - else if (ClassTemplatePartialSpecializationDecl *PartialSpec - = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) - Params = PartialSpec->getTemplateParameters(); - else - return; + if (TagDecl *TD = dyn_cast<TagDecl>(D)) { + for (unsigned i = 0; i < TD->getNumTemplateParameterLists(); ++i) + ParameterLists.push_back(TD->getTemplateParameterList(i)); - for (TemplateParameterList::iterator Param = Params->begin(), - ParamEnd = Params->end(); - Param != ParamEnd; ++Param) { - NamedDecl *Named = cast<NamedDecl>(*Param); - if (Named->getDeclName()) { - S->AddDecl(Named); - IdResolver.AddDecl(Named); + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) { + if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate()) + ParameterLists.push_back(CTD->getTemplateParameters()); } } + + unsigned Count = 0; + for (TemplateParameterList *Params : ParameterLists) { + if (Params->size() > 0) + // Ignore explicit specializations; they don't contribute to the template + // depth. + ++Count; + for (NamedDecl *Param : *Params) { + if (Param->getDeclName()) { + S->AddDecl(Param); + IdResolver.AddDecl(Param); + } + } + } + + return Count; } void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) { |