summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-05-02 02:01:07 +0000
committerHans Wennborg <hans@hanshq.net>2014-05-02 02:01:07 +0000
commitb6d4e8cd4ee065166d4732e271abbc06a74dbdb2 (patch)
tree9fa09c4f0bb722385cdd336c596c8848923010de /clang/lib/Sema/SemaDeclCXX.cpp
parentdb2fc6d75614db2691ee61c442f42cf691b89522 (diff)
downloadbcm5719-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.cpp74
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) {
OpenPOWER on IntegriCloud