Collect multiple levels of template arguments into a new type,
MultiLevelTemplateArgumentList. This is a baby step toward
instantiating member templates; no intended functionality change yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80380 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 4642251..b330ae9 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -28,30 +28,39 @@
/// \brief Retrieve the template argument list that should be used to
/// instantiate the given declaration.
-const TemplateArgumentList &
+MultiLevelTemplateArgumentList
Sema::getTemplateInstantiationArgs(NamedDecl *D) {
- // Template arguments for a class template specialization.
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(D))
- return Spec->getTemplateInstantiationArgs();
-
- // Template arguments for a function template specialization.
- if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
- if (const TemplateArgumentList *TemplateArgs
- = Function->getTemplateSpecializationArgs())
- return *TemplateArgs;
+ // Accumulate the set of template argument lists in this structure.
+ MultiLevelTemplateArgumentList Result;
+
+ DeclContext *Ctx = dyn_cast<DeclContext>(D);
+ if (!Ctx)
+ Ctx = D->getDeclContext();
+
+ for (; !Ctx->isFileContext(); Ctx = Ctx->getParent()) {
+ // Add template arguments from a class template instantiation.
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+ // We're done when we hit an explicit specialization.
+ if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization)
+ break;
- // Template arguments for a member of a class template specialization.
- DeclContext *EnclosingTemplateCtx = D->getDeclContext();
- while (!isa<ClassTemplateSpecializationDecl>(EnclosingTemplateCtx)) {
- assert(!EnclosingTemplateCtx->isFileContext() &&
- "Tried to get the instantiation arguments of a non-template");
- EnclosingTemplateCtx = EnclosingTemplateCtx->getParent();
+ Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
+ continue;
+ }
+
+ // Add template arguments from a function template specialization.
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
+ // FIXME: Check whether this is an explicit specialization.
+ if (const TemplateArgumentList *TemplateArgs
+ = Function->getTemplateSpecializationArgs())
+ Result.addOuterTemplateArguments(TemplateArgs);
+
+ continue;
+ }
}
-
- ClassTemplateSpecializationDecl *EnclosingTemplate
- = cast<ClassTemplateSpecializationDecl>(EnclosingTemplateCtx);
- return EnclosingTemplate->getTemplateInstantiationArgs();
+
+ return Result;
}
Sema::InstantiatingTemplate::