diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-09 23:48:35 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-09 23:48:35 +0000 |
commit | 40808ce6ac04b102c3b56244a635d6b98eed6d97 (patch) | |
tree | 92301d6219bc011b5ef02707aa8251e30d3f0db0 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | e15b486ada22517bd976768cabf80213cef44347 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index faeebc0680..71bba49af9 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -302,9 +302,44 @@ TemplateTypeInstantiator:: 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 |