Implement template instantiation for ClassTemplateSpecializationTypes,
such as replacing 'T' in vector<T>. There are a few aspects to this:
- Extend TemplateArgument to allow arbitrary expressions (an
Expr*), and switch ClassTemplateSpecializationType to store
TemplateArguments rather than it's own type-or-expression
representation.
- ClassTemplateSpecializationType can now store dependent types. In
that case, the canonical type is another
ClassTemplateSpecializationType (with default template arguments
expanded) rather than a declaration (we don't build Decls for
dependent types).
- Split ActOnClassTemplateId into ActOnClassTemplateId (called from
the parser) and CheckClassTemplateId (called from
ActOnClassTemplateId and InstantiateType). They're smart enough to
handle dependent types, now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66509 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index faeebc0..71bba49 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -302,9 +302,44 @@
InstantiateClassTemplateSpecializationType(
const ClassTemplateSpecializationType *T,
unsigned Quals) const {
- // FIXME: Implement this
- assert(false && "Cannot instantiate ClassTemplateSpecializationType yet");
- return QualType();
+ llvm::SmallVector<TemplateArgument, 16> InstantiatedTemplateArgs;
+ InstantiatedTemplateArgs.reserve(T->getNumArgs());
+ for (ClassTemplateSpecializationType::iterator Arg = T->begin(),
+ ArgEnd = T->end();
+ Arg != ArgEnd; ++Arg) {
+ switch (Arg->getKind()) {
+ case TemplateArgument::Type: {
+ QualType T = SemaRef.InstantiateType(Arg->getAsType(),
+ TemplateArgs, NumTemplateArgs,
+ Arg->getLocation(),
+ DeclarationName());
+ if (T.isNull())
+ return QualType();
+
+ InstantiatedTemplateArgs.push_back(
+ TemplateArgument(Arg->getLocation(), T));
+ break;
+ }
+
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ InstantiatedTemplateArgs.push_back(*Arg);
+ break;
+
+ case TemplateArgument::Expression:
+ assert(false && "Cannot instantiate expressions yet");
+ break;
+ }
+ }
+
+ // FIXME: We're missing the locations of the template name, '<', and
+ // '>'.
+ return SemaRef.CheckClassTemplateId(cast<ClassTemplateDecl>(T->getTemplate()),
+ Loc,
+ SourceLocation(),
+ &InstantiatedTemplateArgs[0],
+ InstantiatedTemplateArgs.size(),
+ SourceLocation());
}
QualType