blob: 057b256ddd4ae78972204e0d574f5dc136081ce4 [file] [log] [blame]
Douglas Gregor74296542009-02-27 19:31:52 +00001//===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements C++ template instantiation.
10//
11//===----------------------------------------------------------------------===/
12
13#include "Sema.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Expr.h"
16#include "clang/AST/ExprCXX.h"
17#include "clang/AST/DeclTemplate.h"
18#include "clang/Parse/DeclSpec.h"
19#include "clang/Basic/LangOptions.h"
Douglas Gregorf57dcd02009-02-28 00:25:32 +000020#include "llvm/Support/Compiler.h"
Douglas Gregor74296542009-02-27 19:31:52 +000021
22using namespace clang;
23
Douglas Gregorfee85d62009-03-10 18:03:33 +000024//===----------------------------------------------------------------------===/
25// Template Instantiation Support
26//===----------------------------------------------------------------------===/
27
Douglas Gregor375733c2009-03-10 00:06:19 +000028Sema::InstantiatingTemplate::
29InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
30 ClassTemplateSpecializationDecl *Entity,
31 SourceRange InstantiationRange)
32 : SemaRef(SemaRef) {
33 if (SemaRef.ActiveTemplateInstantiations.size()
34 > SemaRef.getLangOptions().InstantiationDepth) {
35 SemaRef.Diag(PointOfInstantiation,
36 diag::err_template_recursion_depth_exceeded)
37 << SemaRef.getLangOptions().InstantiationDepth
38 << InstantiationRange;
39 SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
40 << SemaRef.getLangOptions().InstantiationDepth;
41 Invalid = true;
42 } else {
43 ActiveTemplateInstantiation Inst;
44 Inst.PointOfInstantiation = PointOfInstantiation;
45 Inst.Entity = Entity;
46 Inst.InstantiationRange = InstantiationRange;
47 SemaRef.ActiveTemplateInstantiations.push_back(Inst);
48 Invalid = false;
49 }
50}
51
52Sema::InstantiatingTemplate::~InstantiatingTemplate() {
53 if (!Invalid)
54 SemaRef.ActiveTemplateInstantiations.pop_back();
55}
56
Douglas Gregorfee85d62009-03-10 18:03:33 +000057/// \brief Post-diagnostic hook for printing the instantiation stack.
58void Sema::PrintInstantiationStackHook(unsigned, void *Cookie) {
Douglas Gregord9572a12009-03-10 18:52:44 +000059 Sema &SemaRef = *static_cast<Sema*>(Cookie);
60 SemaRef.PrintInstantiationStack();
61 SemaRef.LastTemplateInstantiationErrorContext
62 = SemaRef.ActiveTemplateInstantiations.back().Entity;
Douglas Gregorfee85d62009-03-10 18:03:33 +000063}
64
65/// \brief Prints the current instantiation stack through a series of
66/// notes.
67void Sema::PrintInstantiationStack() {
68 for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
69 Active = ActiveTemplateInstantiations.rbegin(),
70 ActiveEnd = ActiveTemplateInstantiations.rend();
71 Active != ActiveEnd;
72 ++Active) {
73 Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
74 diag::note_template_class_instantiation_here)
75 << Context.getTypeDeclType(Active->Entity)
76 << Active->InstantiationRange;
77 }
78}
79
Douglas Gregor74296542009-02-27 19:31:52 +000080//===----------------------------------------------------------------------===/
81// Template Instantiation for Types
82//===----------------------------------------------------------------------===/
Douglas Gregorf57dcd02009-02-28 00:25:32 +000083namespace {
84 class VISIBILITY_HIDDEN TemplateTypeInstantiator {
85 Sema &SemaRef;
86 const TemplateArgument *TemplateArgs;
87 unsigned NumTemplateArgs;
88 SourceLocation Loc;
89 DeclarationName Entity;
Douglas Gregor74296542009-02-27 19:31:52 +000090
Douglas Gregorf57dcd02009-02-28 00:25:32 +000091 public:
92 TemplateTypeInstantiator(Sema &SemaRef,
93 const TemplateArgument *TemplateArgs,
94 unsigned NumTemplateArgs,
95 SourceLocation Loc,
96 DeclarationName Entity)
97 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
98 NumTemplateArgs(NumTemplateArgs), Loc(Loc), Entity(Entity) { }
99
100 QualType operator()(QualType T) const { return Instantiate(T); }
101
102 QualType Instantiate(QualType T) const;
103
104 // Declare instantiate functions for each type.
105#define TYPE(Class, Base) \
106 QualType Instantiate##Class##Type(const Class##Type *T, \
107 unsigned Quals) const;
108#define ABSTRACT_TYPE(Class, Base)
109#include "clang/AST/TypeNodes.def"
110 };
111}
112
113QualType
114TemplateTypeInstantiator::InstantiateExtQualType(const ExtQualType *T,
115 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000116 // FIXME: Implement this
117 assert(false && "Cannot instantiate ExtQualType yet");
118 return QualType();
119}
120
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000121QualType
122TemplateTypeInstantiator::InstantiateBuiltinType(const BuiltinType *T,
123 unsigned Quals) const {
Douglas Gregorc0139ca2009-02-28 01:04:19 +0000124 assert(false && "Builtin types are not dependent and cannot be instantiated");
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000125 return QualType(T, Quals);
Douglas Gregor74296542009-02-27 19:31:52 +0000126}
127
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000128QualType
129TemplateTypeInstantiator::
130InstantiateFixedWidthIntType(const FixedWidthIntType *T, unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000131 // FIXME: Implement this
132 assert(false && "Cannot instantiate FixedWidthIntType yet");
133 return QualType();
134}
135
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000136QualType
137TemplateTypeInstantiator::InstantiateComplexType(const ComplexType *T,
138 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000139 // FIXME: Implement this
140 assert(false && "Cannot instantiate ComplexType yet");
141 return QualType();
142}
143
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000144QualType
145TemplateTypeInstantiator::InstantiatePointerType(const PointerType *T,
146 unsigned Quals) const {
147 QualType PointeeType = Instantiate(T->getPointeeType());
148 if (PointeeType.isNull())
149 return QualType();
150
151 return SemaRef.BuildPointerType(PointeeType, Quals, Loc, Entity);
Douglas Gregor74296542009-02-27 19:31:52 +0000152}
153
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000154QualType
155TemplateTypeInstantiator::InstantiateBlockPointerType(const BlockPointerType *T,
156 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000157 // FIXME: Implement this
158 assert(false && "Cannot instantiate BlockPointerType yet");
159 return QualType();
160}
161
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000162QualType
163TemplateTypeInstantiator::InstantiateReferenceType(const ReferenceType *T,
164 unsigned Quals) const {
165 QualType ReferentType = Instantiate(T->getPointeeType());
166 if (ReferentType.isNull())
167 return QualType();
168
169 return SemaRef.BuildReferenceType(ReferentType, Quals, Loc, Entity);
Douglas Gregor74296542009-02-27 19:31:52 +0000170}
171
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000172QualType
173TemplateTypeInstantiator::
174InstantiateMemberPointerType(const MemberPointerType *T,
175 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000176 // FIXME: Implement this
177 assert(false && "Cannot instantiate MemberPointerType yet");
178 return QualType();
179}
180
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000181QualType
182TemplateTypeInstantiator::
183InstantiateConstantArrayType(const ConstantArrayType *T,
184 unsigned Quals) const {
185 QualType ElementType = Instantiate(T->getElementType());
186 if (ElementType.isNull())
187 return ElementType;
188
189 // Build a temporary integer literal to specify the size for
190 // BuildArrayType. Since we have already checked the size as part of
191 // creating the dependent array type in the first place, we know
192 // there aren't any errors.
Douglas Gregor448fcd32009-03-09 20:07:22 +0000193 // FIXME: Is IntTy big enough? Maybe not, but LongLongTy causes
194 // problems that I have yet to investigate.
195 IntegerLiteral ArraySize(T->getSize(), SemaRef.Context.IntTy, Loc);
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000196 return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(),
197 &ArraySize, T->getIndexTypeQualifier(),
198 Loc, Entity);
Douglas Gregor74296542009-02-27 19:31:52 +0000199}
200
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000201QualType
202TemplateTypeInstantiator::
203InstantiateIncompleteArrayType(const IncompleteArrayType *T,
204 unsigned Quals) const {
205 QualType ElementType = Instantiate(T->getElementType());
206 if (ElementType.isNull())
207 return ElementType;
208
209 return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(),
210 0, T->getIndexTypeQualifier(),
211 Loc, Entity);
Douglas Gregor74296542009-02-27 19:31:52 +0000212}
213
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000214QualType
215TemplateTypeInstantiator::
216InstantiateVariableArrayType(const VariableArrayType *T,
217 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000218 // FIXME: Implement this
219 assert(false && "Cannot instantiate VariableArrayType yet");
220 return QualType();
221}
222
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000223QualType
224TemplateTypeInstantiator::
225InstantiateDependentSizedArrayType(const DependentSizedArrayType *T,
226 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000227 // FIXME: Implement this
228 assert(false && "Cannot instantiate DependentSizedArrayType yet");
229 return QualType();
230}
231
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000232QualType
233TemplateTypeInstantiator::InstantiateVectorType(const VectorType *T,
234 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000235 // FIXME: Implement this
236 assert(false && "Cannot instantiate VectorType yet");
237 return QualType();
238}
239
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000240QualType
241TemplateTypeInstantiator::InstantiateExtVectorType(const ExtVectorType *T,
242 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000243 // FIXME: Implement this
244 assert(false && "Cannot instantiate ExtVectorType yet");
245 return QualType();
246}
247
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000248QualType
249TemplateTypeInstantiator::
250InstantiateFunctionProtoType(const FunctionProtoType *T,
251 unsigned Quals) const {
Douglas Gregorc0139ca2009-02-28 01:04:19 +0000252 QualType ResultType = Instantiate(T->getResultType());
253 if (ResultType.isNull())
254 return ResultType;
255
256 llvm::SmallVector<QualType, 16> ParamTypes;
257 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
258 ParamEnd = T->arg_type_end();
259 Param != ParamEnd; ++Param) {
260 QualType P = Instantiate(*Param);
261 if (P.isNull())
262 return P;
263
264 ParamTypes.push_back(P);
265 }
266
267 return SemaRef.BuildFunctionType(ResultType, &ParamTypes[0],
268 ParamTypes.size(),
269 T->isVariadic(), T->getTypeQuals(),
270 Loc, Entity);
Douglas Gregor74296542009-02-27 19:31:52 +0000271}
272
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000273QualType
274TemplateTypeInstantiator::
275InstantiateFunctionNoProtoType(const FunctionNoProtoType *T,
276 unsigned Quals) const {
Douglas Gregorc0139ca2009-02-28 01:04:19 +0000277 assert(false && "Functions without prototypes cannot be dependent.");
Douglas Gregor74296542009-02-27 19:31:52 +0000278 return QualType();
279}
280
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000281QualType
282TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T,
283 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000284 // FIXME: Implement this
285 assert(false && "Cannot instantiate TypedefType yet");
286 return QualType();
287}
288
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000289QualType
290TemplateTypeInstantiator::InstantiateTypeOfExprType(const TypeOfExprType *T,
291 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000292 // FIXME: Implement this
293 assert(false && "Cannot instantiate TypeOfExprType yet");
294 return QualType();
295}
296
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000297QualType
298TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T,
299 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000300 // FIXME: Implement this
301 assert(false && "Cannot instantiate TypeOfType yet");
302 return QualType();
303}
304
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000305QualType
306TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
307 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000308 // FIXME: Implement this
309 assert(false && "Cannot instantiate RecordType yet");
310 return QualType();
311}
312
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000313QualType
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000314TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T,
315 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000316 // FIXME: Implement this
317 assert(false && "Cannot instantiate EnumType yet");
318 return QualType();
319}
320
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000321QualType
322TemplateTypeInstantiator::
323InstantiateTemplateTypeParmType(const TemplateTypeParmType *T,
324 unsigned Quals) const {
Douglas Gregor74296542009-02-27 19:31:52 +0000325 if (T->getDepth() == 0) {
326 // Replace the template type parameter with its corresponding
327 // template argument.
328 assert(T->getIndex() < NumTemplateArgs && "Wrong # of template args");
329 assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type &&
330 "Template argument kind mismatch");
331 QualType Result = TemplateArgs[T->getIndex()].getAsType();
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000332 if (Result.isNull() || !Quals)
Douglas Gregor74296542009-02-27 19:31:52 +0000333 return Result;
334
335 // C++ [dcl.ref]p1:
336 // [...] Cv-qualified references are ill-formed except when
337 // the cv-qualifiers are introduced through the use of a
338 // typedef (7.1.3) or of a template type argument (14.3), in
339 // which case the cv-qualifiers are ignored.
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000340 if (Quals && Result->isReferenceType())
341 Quals = 0;
Douglas Gregor74296542009-02-27 19:31:52 +0000342
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000343 return QualType(Result.getTypePtr(), Quals | Result.getCVRQualifiers());
Douglas Gregor74296542009-02-27 19:31:52 +0000344 }
345
346 // The template type parameter comes from an inner template (e.g.,
347 // the template parameter list of a member template inside the
348 // template we are instantiating). Create a new template type
349 // parameter with the template "level" reduced by one.
350 return SemaRef.Context.getTemplateTypeParmType(T->getDepth() - 1,
351 T->getIndex(),
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000352 T->getName())
353 .getQualifiedType(Quals);
Douglas Gregor74296542009-02-27 19:31:52 +0000354}
355
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000356QualType
357TemplateTypeInstantiator::
358InstantiateClassTemplateSpecializationType(
359 const ClassTemplateSpecializationType *T,
360 unsigned Quals) const {
Douglas Gregorf9ff4b12009-03-09 23:48:35 +0000361 llvm::SmallVector<TemplateArgument, 16> InstantiatedTemplateArgs;
362 InstantiatedTemplateArgs.reserve(T->getNumArgs());
363 for (ClassTemplateSpecializationType::iterator Arg = T->begin(),
364 ArgEnd = T->end();
365 Arg != ArgEnd; ++Arg) {
366 switch (Arg->getKind()) {
367 case TemplateArgument::Type: {
368 QualType T = SemaRef.InstantiateType(Arg->getAsType(),
369 TemplateArgs, NumTemplateArgs,
370 Arg->getLocation(),
371 DeclarationName());
372 if (T.isNull())
373 return QualType();
374
375 InstantiatedTemplateArgs.push_back(
376 TemplateArgument(Arg->getLocation(), T));
377 break;
378 }
379
380 case TemplateArgument::Declaration:
381 case TemplateArgument::Integral:
382 InstantiatedTemplateArgs.push_back(*Arg);
383 break;
384
385 case TemplateArgument::Expression:
386 assert(false && "Cannot instantiate expressions yet");
387 break;
388 }
389 }
390
391 // FIXME: We're missing the locations of the template name, '<', and
392 // '>'.
393 return SemaRef.CheckClassTemplateId(cast<ClassTemplateDecl>(T->getTemplate()),
394 Loc,
395 SourceLocation(),
396 &InstantiatedTemplateArgs[0],
397 InstantiatedTemplateArgs.size(),
398 SourceLocation());
Douglas Gregor74296542009-02-27 19:31:52 +0000399}
400
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000401QualType
402TemplateTypeInstantiator::
403InstantiateObjCInterfaceType(const ObjCInterfaceType *T,
404 unsigned Quals) const {
405 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor74296542009-02-27 19:31:52 +0000406 return QualType();
407}
408
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000409QualType
410TemplateTypeInstantiator::
411InstantiateObjCQualifiedInterfaceType(const ObjCQualifiedInterfaceType *T,
412 unsigned Quals) const {
413 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor74296542009-02-27 19:31:52 +0000414 return QualType();
415}
416
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000417QualType
418TemplateTypeInstantiator::
419InstantiateObjCQualifiedIdType(const ObjCQualifiedIdType *T,
420 unsigned Quals) const {
421 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor74296542009-02-27 19:31:52 +0000422 return QualType();
423}
424
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000425QualType
426TemplateTypeInstantiator::
427InstantiateObjCQualifiedClassType(const ObjCQualifiedClassType *T,
428 unsigned Quals) const {
429 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor74296542009-02-27 19:31:52 +0000430 return QualType();
431}
432
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000433/// \brief The actual implementation of Sema::InstantiateType().
434QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
435 // If T is not a dependent type, there is nothing to do.
436 if (!T->isDependentType())
437 return T;
438
439 switch (T->getTypeClass()) {
440#define TYPE(Class, Base) \
441 case Type::Class: \
442 return Instantiate##Class##Type(cast<Class##Type>(T.getTypePtr()), \
443 T.getCVRQualifiers());
444#define ABSTRACT_TYPE(Class, Base)
445#include "clang/AST/TypeNodes.def"
446 }
447
448 assert(false && "Not all types have been decoded for instantiation");
449 return QualType();
450}
Douglas Gregor74296542009-02-27 19:31:52 +0000451
452/// \brief Instantiate the type T with a given set of template arguments.
453///
454/// This routine substitutes the given template arguments into the
455/// type T and produces the instantiated type.
456///
457/// \param T the type into which the template arguments will be
458/// substituted. If this type is not dependent, it will be returned
459/// immediately.
460///
461/// \param TemplateArgs the template arguments that will be
462/// substituted for the top-level template parameters within T.
463///
464/// \param NumTemplateArgs the number of template arguments provided
465/// by TemplateArgs.
466///
467/// \param Loc the location in the source code where this substitution
468/// is being performed. It will typically be the location of the
469/// declarator (if we're instantiating the type of some declaration)
470/// or the location of the type in the source code (if, e.g., we're
471/// instantiating the type of a cast expression).
472///
473/// \param Entity the name of the entity associated with a declaration
474/// being instantiated (if any). May be empty to indicate that there
475/// is no such entity (if, e.g., this is a type that occurs as part of
476/// a cast expression) or that the entity has no name (e.g., an
477/// unnamed function parameter).
478///
479/// \returns If the instantiation succeeds, the instantiated
480/// type. Otherwise, produces diagnostics and returns a NULL type.
481QualType Sema::InstantiateType(QualType T,
482 const TemplateArgument *TemplateArgs,
483 unsigned NumTemplateArgs,
484 SourceLocation Loc, DeclarationName Entity) {
485 // If T is not a dependent type, there is nothing to do.
486 if (!T->isDependentType())
487 return T;
488
Douglas Gregorf57dcd02009-02-28 00:25:32 +0000489 TemplateTypeInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs,
490 Loc, Entity);
491 return Instantiator(T);
Douglas Gregor74296542009-02-27 19:31:52 +0000492}
Douglas Gregored3a3982009-03-03 04:44:36 +0000493
494/// \brief Instantiate the base class specifiers of the given class
495/// template specialization.
496///
497/// Produces a diagnostic and returns true on error, returns false and
498/// attaches the instantiated base classes to the class template
499/// specialization if successful.
500bool
501Sema::InstantiateBaseSpecifiers(
502 ClassTemplateSpecializationDecl *ClassTemplateSpec,
503 ClassTemplateDecl *ClassTemplate) {
504 bool Invalid = false;
505 llvm::SmallVector<CXXBaseSpecifier*, 8> InstantiatedBases;
506 for (ClassTemplateSpecializationDecl::base_class_iterator
507 Base = ClassTemplate->getTemplatedDecl()->bases_begin(),
508 BaseEnd = ClassTemplate->getTemplatedDecl()->bases_end();
Douglas Gregord9572a12009-03-10 18:52:44 +0000509 Base != BaseEnd; ++Base) {
Douglas Gregored3a3982009-03-03 04:44:36 +0000510 if (!Base->getType()->isDependentType()) {
511 // FIXME: Allocate via ASTContext
512 InstantiatedBases.push_back(new CXXBaseSpecifier(*Base));
513 continue;
514 }
515
516 QualType BaseType = InstantiateType(Base->getType(),
517 ClassTemplateSpec->getTemplateArgs(),
518 ClassTemplateSpec->getNumTemplateArgs(),
519 Base->getSourceRange().getBegin(),
520 DeclarationName());
521 if (BaseType.isNull()) {
522 Invalid = true;
523 continue;
524 }
525
526 if (CXXBaseSpecifier *InstantiatedBase
527 = CheckBaseSpecifier(ClassTemplateSpec,
528 Base->getSourceRange(),
529 Base->isVirtual(),
530 Base->getAccessSpecifierAsWritten(),
531 BaseType,
532 /*FIXME: Not totally accurate */
533 Base->getSourceRange().getBegin()))
534 InstantiatedBases.push_back(InstantiatedBase);
535 else
536 Invalid = true;
537 }
538
Douglas Gregord9572a12009-03-10 18:52:44 +0000539 if (!Invalid &&
540 AttachBaseSpecifiers(ClassTemplateSpec, &InstantiatedBases[0],
Douglas Gregored3a3982009-03-03 04:44:36 +0000541 InstantiatedBases.size()))
542 Invalid = true;
543
544 return Invalid;
545}
546
547bool
548Sema::InstantiateClassTemplateSpecialization(
549 ClassTemplateSpecializationDecl *ClassTemplateSpec,
550 bool ExplicitInstantiation) {
551 // Perform the actual instantiation on the canonical declaration.
552 ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
553 Context.getCanonicalDecl(ClassTemplateSpec));
554
555 // We can only instantiate something that hasn't already been
556 // instantiated or specialized. Fail without any diagnostics: our
557 // caller will provide an error message.
558 if (ClassTemplateSpec->getSpecializationKind() != TSK_Undeclared)
559 return true;
560
561 // FIXME: Push this class template instantiation onto the
562 // instantiation stack, checking for recursion that exceeds a
563 // certain depth.
564
565 // FIXME: Perform class template partial specialization to select
566 // the best template.
567 ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
568
569 if (!Template->getTemplatedDecl()->getDefinition(Context)) {
570 Diag(ClassTemplateSpec->getLocation(),
571 diag::err_template_implicit_instantiate_undefined)
572 << Context.getTypeDeclType(ClassTemplateSpec);
573 Diag(Template->getTemplatedDecl()->getLocation(),
574 diag::note_template_decl_here);
575 return true;
576 }
577
578 // Note that this is an instantiation.
579 ClassTemplateSpec->setSpecializationKind(
580 ExplicitInstantiation? TSK_ExplicitInstantiation
581 : TSK_ImplicitInstantiation);
582
583
584 bool Invalid = false;
585
Douglas Gregor375733c2009-03-10 00:06:19 +0000586 InstantiatingTemplate Inst(*this, ClassTemplateSpec->getLocation(),
587 ClassTemplateSpec);
588 if (Inst)
589 return true;
590
Douglas Gregored3a3982009-03-03 04:44:36 +0000591 // Enter the scope of this instantiation. We don't use
592 // PushDeclContext because we don't have a scope.
593 DeclContext *PreviousContext = CurContext;
594 CurContext = ClassTemplateSpec;
595
596 // Start the definition of this instantiation.
597 ClassTemplateSpec->startDefinition();
598
599 // FIXME: Create the injected-class-name for the
600 // instantiation. Should this be a typedef or something like it?
601
602 // Instantiate the base class specifiers.
603 if (InstantiateBaseSpecifiers(ClassTemplateSpec, Template))
604 Invalid = true;
605
606 // FIXME: Instantiate all of the members.
607
608 // Add any implicitly-declared members that we might need.
609 AddImplicitlyDeclaredMembersToClass(ClassTemplateSpec);
610
611 // Finish the definition of this instantiation.
612 // FIXME: ActOnFields does more checking, which we'll eventually need.
613 ClassTemplateSpec->completeDefinition(Context);
614
615 // Exit the scope of this instantiation.
616 CurContext = PreviousContext;
617
618 return Invalid;
619}