blob: 71bba49af9d5d8272fa9229af57036679fd0d3f0 [file] [log] [blame]
Douglas Gregor99ebf652009-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 Gregorcd281c32009-02-28 00:25:32 +000020#include "llvm/Support/Compiler.h"
Douglas Gregor99ebf652009-02-27 19:31:52 +000021
22using namespace clang;
23
24//===----------------------------------------------------------------------===/
25// Template Instantiation for Types
26//===----------------------------------------------------------------------===/
Douglas Gregorcd281c32009-02-28 00:25:32 +000027namespace {
28 class VISIBILITY_HIDDEN TemplateTypeInstantiator {
29 Sema &SemaRef;
30 const TemplateArgument *TemplateArgs;
31 unsigned NumTemplateArgs;
32 SourceLocation Loc;
33 DeclarationName Entity;
Douglas Gregor99ebf652009-02-27 19:31:52 +000034
Douglas Gregorcd281c32009-02-28 00:25:32 +000035 public:
36 TemplateTypeInstantiator(Sema &SemaRef,
37 const TemplateArgument *TemplateArgs,
38 unsigned NumTemplateArgs,
39 SourceLocation Loc,
40 DeclarationName Entity)
41 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
42 NumTemplateArgs(NumTemplateArgs), Loc(Loc), Entity(Entity) { }
43
44 QualType operator()(QualType T) const { return Instantiate(T); }
45
46 QualType Instantiate(QualType T) const;
47
48 // Declare instantiate functions for each type.
49#define TYPE(Class, Base) \
50 QualType Instantiate##Class##Type(const Class##Type *T, \
51 unsigned Quals) const;
52#define ABSTRACT_TYPE(Class, Base)
53#include "clang/AST/TypeNodes.def"
54 };
55}
56
57QualType
58TemplateTypeInstantiator::InstantiateExtQualType(const ExtQualType *T,
59 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +000060 // FIXME: Implement this
61 assert(false && "Cannot instantiate ExtQualType yet");
62 return QualType();
63}
64
Douglas Gregorcd281c32009-02-28 00:25:32 +000065QualType
66TemplateTypeInstantiator::InstantiateBuiltinType(const BuiltinType *T,
67 unsigned Quals) const {
Douglas Gregor724651c2009-02-28 01:04:19 +000068 assert(false && "Builtin types are not dependent and cannot be instantiated");
Douglas Gregorcd281c32009-02-28 00:25:32 +000069 return QualType(T, Quals);
Douglas Gregor99ebf652009-02-27 19:31:52 +000070}
71
Douglas Gregorcd281c32009-02-28 00:25:32 +000072QualType
73TemplateTypeInstantiator::
74InstantiateFixedWidthIntType(const FixedWidthIntType *T, unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +000075 // FIXME: Implement this
76 assert(false && "Cannot instantiate FixedWidthIntType yet");
77 return QualType();
78}
79
Douglas Gregorcd281c32009-02-28 00:25:32 +000080QualType
81TemplateTypeInstantiator::InstantiateComplexType(const ComplexType *T,
82 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +000083 // FIXME: Implement this
84 assert(false && "Cannot instantiate ComplexType yet");
85 return QualType();
86}
87
Douglas Gregorcd281c32009-02-28 00:25:32 +000088QualType
89TemplateTypeInstantiator::InstantiatePointerType(const PointerType *T,
90 unsigned Quals) const {
91 QualType PointeeType = Instantiate(T->getPointeeType());
92 if (PointeeType.isNull())
93 return QualType();
94
95 return SemaRef.BuildPointerType(PointeeType, Quals, Loc, Entity);
Douglas Gregor99ebf652009-02-27 19:31:52 +000096}
97
Douglas Gregorcd281c32009-02-28 00:25:32 +000098QualType
99TemplateTypeInstantiator::InstantiateBlockPointerType(const BlockPointerType *T,
100 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000101 // FIXME: Implement this
102 assert(false && "Cannot instantiate BlockPointerType yet");
103 return QualType();
104}
105
Douglas Gregorcd281c32009-02-28 00:25:32 +0000106QualType
107TemplateTypeInstantiator::InstantiateReferenceType(const ReferenceType *T,
108 unsigned Quals) const {
109 QualType ReferentType = Instantiate(T->getPointeeType());
110 if (ReferentType.isNull())
111 return QualType();
112
113 return SemaRef.BuildReferenceType(ReferentType, Quals, Loc, Entity);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000114}
115
Douglas Gregorcd281c32009-02-28 00:25:32 +0000116QualType
117TemplateTypeInstantiator::
118InstantiateMemberPointerType(const MemberPointerType *T,
119 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000120 // FIXME: Implement this
121 assert(false && "Cannot instantiate MemberPointerType yet");
122 return QualType();
123}
124
Douglas Gregorcd281c32009-02-28 00:25:32 +0000125QualType
126TemplateTypeInstantiator::
127InstantiateConstantArrayType(const ConstantArrayType *T,
128 unsigned Quals) const {
129 QualType ElementType = Instantiate(T->getElementType());
130 if (ElementType.isNull())
131 return ElementType;
132
133 // Build a temporary integer literal to specify the size for
134 // BuildArrayType. Since we have already checked the size as part of
135 // creating the dependent array type in the first place, we know
136 // there aren't any errors.
Douglas Gregor8d217212009-03-09 20:07:22 +0000137 // FIXME: Is IntTy big enough? Maybe not, but LongLongTy causes
138 // problems that I have yet to investigate.
139 IntegerLiteral ArraySize(T->getSize(), SemaRef.Context.IntTy, Loc);
Douglas Gregorcd281c32009-02-28 00:25:32 +0000140 return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(),
141 &ArraySize, T->getIndexTypeQualifier(),
142 Loc, Entity);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000143}
144
Douglas Gregorcd281c32009-02-28 00:25:32 +0000145QualType
146TemplateTypeInstantiator::
147InstantiateIncompleteArrayType(const IncompleteArrayType *T,
148 unsigned Quals) const {
149 QualType ElementType = Instantiate(T->getElementType());
150 if (ElementType.isNull())
151 return ElementType;
152
153 return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(),
154 0, T->getIndexTypeQualifier(),
155 Loc, Entity);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000156}
157
Douglas Gregorcd281c32009-02-28 00:25:32 +0000158QualType
159TemplateTypeInstantiator::
160InstantiateVariableArrayType(const VariableArrayType *T,
161 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000162 // FIXME: Implement this
163 assert(false && "Cannot instantiate VariableArrayType yet");
164 return QualType();
165}
166
Douglas Gregorcd281c32009-02-28 00:25:32 +0000167QualType
168TemplateTypeInstantiator::
169InstantiateDependentSizedArrayType(const DependentSizedArrayType *T,
170 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000171 // FIXME: Implement this
172 assert(false && "Cannot instantiate DependentSizedArrayType yet");
173 return QualType();
174}
175
Douglas Gregorcd281c32009-02-28 00:25:32 +0000176QualType
177TemplateTypeInstantiator::InstantiateVectorType(const VectorType *T,
178 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000179 // FIXME: Implement this
180 assert(false && "Cannot instantiate VectorType yet");
181 return QualType();
182}
183
Douglas Gregorcd281c32009-02-28 00:25:32 +0000184QualType
185TemplateTypeInstantiator::InstantiateExtVectorType(const ExtVectorType *T,
186 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000187 // FIXME: Implement this
188 assert(false && "Cannot instantiate ExtVectorType yet");
189 return QualType();
190}
191
Douglas Gregorcd281c32009-02-28 00:25:32 +0000192QualType
193TemplateTypeInstantiator::
194InstantiateFunctionProtoType(const FunctionProtoType *T,
195 unsigned Quals) const {
Douglas Gregor724651c2009-02-28 01:04:19 +0000196 QualType ResultType = Instantiate(T->getResultType());
197 if (ResultType.isNull())
198 return ResultType;
199
200 llvm::SmallVector<QualType, 16> ParamTypes;
201 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
202 ParamEnd = T->arg_type_end();
203 Param != ParamEnd; ++Param) {
204 QualType P = Instantiate(*Param);
205 if (P.isNull())
206 return P;
207
208 ParamTypes.push_back(P);
209 }
210
211 return SemaRef.BuildFunctionType(ResultType, &ParamTypes[0],
212 ParamTypes.size(),
213 T->isVariadic(), T->getTypeQuals(),
214 Loc, Entity);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000215}
216
Douglas Gregorcd281c32009-02-28 00:25:32 +0000217QualType
218TemplateTypeInstantiator::
219InstantiateFunctionNoProtoType(const FunctionNoProtoType *T,
220 unsigned Quals) const {
Douglas Gregor724651c2009-02-28 01:04:19 +0000221 assert(false && "Functions without prototypes cannot be dependent.");
Douglas Gregor99ebf652009-02-27 19:31:52 +0000222 return QualType();
223}
224
Douglas Gregorcd281c32009-02-28 00:25:32 +0000225QualType
226TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T,
227 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000228 // FIXME: Implement this
229 assert(false && "Cannot instantiate TypedefType yet");
230 return QualType();
231}
232
Douglas Gregorcd281c32009-02-28 00:25:32 +0000233QualType
234TemplateTypeInstantiator::InstantiateTypeOfExprType(const TypeOfExprType *T,
235 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000236 // FIXME: Implement this
237 assert(false && "Cannot instantiate TypeOfExprType yet");
238 return QualType();
239}
240
Douglas Gregorcd281c32009-02-28 00:25:32 +0000241QualType
242TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T,
243 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000244 // FIXME: Implement this
245 assert(false && "Cannot instantiate TypeOfType yet");
246 return QualType();
247}
248
Douglas Gregorcd281c32009-02-28 00:25:32 +0000249QualType
250TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
251 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000252 // FIXME: Implement this
253 assert(false && "Cannot instantiate RecordType yet");
254 return QualType();
255}
256
Douglas Gregorcd281c32009-02-28 00:25:32 +0000257QualType
Douglas Gregorcd281c32009-02-28 00:25:32 +0000258TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T,
259 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000260 // FIXME: Implement this
261 assert(false && "Cannot instantiate EnumType yet");
262 return QualType();
263}
264
Douglas Gregorcd281c32009-02-28 00:25:32 +0000265QualType
266TemplateTypeInstantiator::
267InstantiateTemplateTypeParmType(const TemplateTypeParmType *T,
268 unsigned Quals) const {
Douglas Gregor99ebf652009-02-27 19:31:52 +0000269 if (T->getDepth() == 0) {
270 // Replace the template type parameter with its corresponding
271 // template argument.
272 assert(T->getIndex() < NumTemplateArgs && "Wrong # of template args");
273 assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type &&
274 "Template argument kind mismatch");
275 QualType Result = TemplateArgs[T->getIndex()].getAsType();
Douglas Gregorcd281c32009-02-28 00:25:32 +0000276 if (Result.isNull() || !Quals)
Douglas Gregor99ebf652009-02-27 19:31:52 +0000277 return Result;
278
279 // C++ [dcl.ref]p1:
280 // [...] Cv-qualified references are ill-formed except when
281 // the cv-qualifiers are introduced through the use of a
282 // typedef (7.1.3) or of a template type argument (14.3), in
283 // which case the cv-qualifiers are ignored.
Douglas Gregorcd281c32009-02-28 00:25:32 +0000284 if (Quals && Result->isReferenceType())
285 Quals = 0;
Douglas Gregor99ebf652009-02-27 19:31:52 +0000286
Douglas Gregorcd281c32009-02-28 00:25:32 +0000287 return QualType(Result.getTypePtr(), Quals | Result.getCVRQualifiers());
Douglas Gregor99ebf652009-02-27 19:31:52 +0000288 }
289
290 // The template type parameter comes from an inner template (e.g.,
291 // the template parameter list of a member template inside the
292 // template we are instantiating). Create a new template type
293 // parameter with the template "level" reduced by one.
294 return SemaRef.Context.getTemplateTypeParmType(T->getDepth() - 1,
295 T->getIndex(),
Douglas Gregorcd281c32009-02-28 00:25:32 +0000296 T->getName())
297 .getQualifiedType(Quals);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000298}
299
Douglas Gregorcd281c32009-02-28 00:25:32 +0000300QualType
301TemplateTypeInstantiator::
302InstantiateClassTemplateSpecializationType(
303 const ClassTemplateSpecializationType *T,
304 unsigned Quals) const {
Douglas Gregor40808ce2009-03-09 23:48:35 +0000305 llvm::SmallVector<TemplateArgument, 16> InstantiatedTemplateArgs;
306 InstantiatedTemplateArgs.reserve(T->getNumArgs());
307 for (ClassTemplateSpecializationType::iterator Arg = T->begin(),
308 ArgEnd = T->end();
309 Arg != ArgEnd; ++Arg) {
310 switch (Arg->getKind()) {
311 case TemplateArgument::Type: {
312 QualType T = SemaRef.InstantiateType(Arg->getAsType(),
313 TemplateArgs, NumTemplateArgs,
314 Arg->getLocation(),
315 DeclarationName());
316 if (T.isNull())
317 return QualType();
318
319 InstantiatedTemplateArgs.push_back(
320 TemplateArgument(Arg->getLocation(), T));
321 break;
322 }
323
324 case TemplateArgument::Declaration:
325 case TemplateArgument::Integral:
326 InstantiatedTemplateArgs.push_back(*Arg);
327 break;
328
329 case TemplateArgument::Expression:
330 assert(false && "Cannot instantiate expressions yet");
331 break;
332 }
333 }
334
335 // FIXME: We're missing the locations of the template name, '<', and
336 // '>'.
337 return SemaRef.CheckClassTemplateId(cast<ClassTemplateDecl>(T->getTemplate()),
338 Loc,
339 SourceLocation(),
340 &InstantiatedTemplateArgs[0],
341 InstantiatedTemplateArgs.size(),
342 SourceLocation());
Douglas Gregor99ebf652009-02-27 19:31:52 +0000343}
344
Douglas Gregorcd281c32009-02-28 00:25:32 +0000345QualType
346TemplateTypeInstantiator::
347InstantiateObjCInterfaceType(const ObjCInterfaceType *T,
348 unsigned Quals) const {
349 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor99ebf652009-02-27 19:31:52 +0000350 return QualType();
351}
352
Douglas Gregorcd281c32009-02-28 00:25:32 +0000353QualType
354TemplateTypeInstantiator::
355InstantiateObjCQualifiedInterfaceType(const ObjCQualifiedInterfaceType *T,
356 unsigned Quals) const {
357 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor99ebf652009-02-27 19:31:52 +0000358 return QualType();
359}
360
Douglas Gregorcd281c32009-02-28 00:25:32 +0000361QualType
362TemplateTypeInstantiator::
363InstantiateObjCQualifiedIdType(const ObjCQualifiedIdType *T,
364 unsigned Quals) const {
365 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor99ebf652009-02-27 19:31:52 +0000366 return QualType();
367}
368
Douglas Gregorcd281c32009-02-28 00:25:32 +0000369QualType
370TemplateTypeInstantiator::
371InstantiateObjCQualifiedClassType(const ObjCQualifiedClassType *T,
372 unsigned Quals) const {
373 assert(false && "Objective-C types cannot be dependent");
Douglas Gregor99ebf652009-02-27 19:31:52 +0000374 return QualType();
375}
376
Douglas Gregorcd281c32009-02-28 00:25:32 +0000377/// \brief The actual implementation of Sema::InstantiateType().
378QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
379 // If T is not a dependent type, there is nothing to do.
380 if (!T->isDependentType())
381 return T;
382
383 switch (T->getTypeClass()) {
384#define TYPE(Class, Base) \
385 case Type::Class: \
386 return Instantiate##Class##Type(cast<Class##Type>(T.getTypePtr()), \
387 T.getCVRQualifiers());
388#define ABSTRACT_TYPE(Class, Base)
389#include "clang/AST/TypeNodes.def"
390 }
391
392 assert(false && "Not all types have been decoded for instantiation");
393 return QualType();
394}
Douglas Gregor99ebf652009-02-27 19:31:52 +0000395
396/// \brief Instantiate the type T with a given set of template arguments.
397///
398/// This routine substitutes the given template arguments into the
399/// type T and produces the instantiated type.
400///
401/// \param T the type into which the template arguments will be
402/// substituted. If this type is not dependent, it will be returned
403/// immediately.
404///
405/// \param TemplateArgs the template arguments that will be
406/// substituted for the top-level template parameters within T.
407///
408/// \param NumTemplateArgs the number of template arguments provided
409/// by TemplateArgs.
410///
411/// \param Loc the location in the source code where this substitution
412/// is being performed. It will typically be the location of the
413/// declarator (if we're instantiating the type of some declaration)
414/// or the location of the type in the source code (if, e.g., we're
415/// instantiating the type of a cast expression).
416///
417/// \param Entity the name of the entity associated with a declaration
418/// being instantiated (if any). May be empty to indicate that there
419/// is no such entity (if, e.g., this is a type that occurs as part of
420/// a cast expression) or that the entity has no name (e.g., an
421/// unnamed function parameter).
422///
423/// \returns If the instantiation succeeds, the instantiated
424/// type. Otherwise, produces diagnostics and returns a NULL type.
425QualType Sema::InstantiateType(QualType T,
426 const TemplateArgument *TemplateArgs,
427 unsigned NumTemplateArgs,
428 SourceLocation Loc, DeclarationName Entity) {
429 // If T is not a dependent type, there is nothing to do.
430 if (!T->isDependentType())
431 return T;
432
Douglas Gregorcd281c32009-02-28 00:25:32 +0000433 TemplateTypeInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs,
434 Loc, Entity);
435 return Instantiator(T);
Douglas Gregor99ebf652009-02-27 19:31:52 +0000436}
Douglas Gregor2943aed2009-03-03 04:44:36 +0000437
438/// \brief Instantiate the base class specifiers of the given class
439/// template specialization.
440///
441/// Produces a diagnostic and returns true on error, returns false and
442/// attaches the instantiated base classes to the class template
443/// specialization if successful.
444bool
445Sema::InstantiateBaseSpecifiers(
446 ClassTemplateSpecializationDecl *ClassTemplateSpec,
447 ClassTemplateDecl *ClassTemplate) {
448 bool Invalid = false;
449 llvm::SmallVector<CXXBaseSpecifier*, 8> InstantiatedBases;
450 for (ClassTemplateSpecializationDecl::base_class_iterator
451 Base = ClassTemplate->getTemplatedDecl()->bases_begin(),
452 BaseEnd = ClassTemplate->getTemplatedDecl()->bases_end();
453 Base != BaseEnd && !Invalid; ++Base) {
454 if (!Base->getType()->isDependentType()) {
455 // FIXME: Allocate via ASTContext
456 InstantiatedBases.push_back(new CXXBaseSpecifier(*Base));
457 continue;
458 }
459
460 QualType BaseType = InstantiateType(Base->getType(),
461 ClassTemplateSpec->getTemplateArgs(),
462 ClassTemplateSpec->getNumTemplateArgs(),
463 Base->getSourceRange().getBegin(),
464 DeclarationName());
465 if (BaseType.isNull()) {
466 Invalid = true;
467 continue;
468 }
469
470 if (CXXBaseSpecifier *InstantiatedBase
471 = CheckBaseSpecifier(ClassTemplateSpec,
472 Base->getSourceRange(),
473 Base->isVirtual(),
474 Base->getAccessSpecifierAsWritten(),
475 BaseType,
476 /*FIXME: Not totally accurate */
477 Base->getSourceRange().getBegin()))
478 InstantiatedBases.push_back(InstantiatedBase);
479 else
480 Invalid = true;
481 }
482
483 if (AttachBaseSpecifiers(ClassTemplateSpec, &InstantiatedBases[0],
484 InstantiatedBases.size()))
485 Invalid = true;
486
487 return Invalid;
488}
489
490bool
491Sema::InstantiateClassTemplateSpecialization(
492 ClassTemplateSpecializationDecl *ClassTemplateSpec,
493 bool ExplicitInstantiation) {
494 // Perform the actual instantiation on the canonical declaration.
495 ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
496 Context.getCanonicalDecl(ClassTemplateSpec));
497
498 // We can only instantiate something that hasn't already been
499 // instantiated or specialized. Fail without any diagnostics: our
500 // caller will provide an error message.
501 if (ClassTemplateSpec->getSpecializationKind() != TSK_Undeclared)
502 return true;
503
504 // FIXME: Push this class template instantiation onto the
505 // instantiation stack, checking for recursion that exceeds a
506 // certain depth.
507
508 // FIXME: Perform class template partial specialization to select
509 // the best template.
510 ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
511
512 if (!Template->getTemplatedDecl()->getDefinition(Context)) {
513 Diag(ClassTemplateSpec->getLocation(),
514 diag::err_template_implicit_instantiate_undefined)
515 << Context.getTypeDeclType(ClassTemplateSpec);
516 Diag(Template->getTemplatedDecl()->getLocation(),
517 diag::note_template_decl_here);
518 return true;
519 }
520
521 // Note that this is an instantiation.
522 ClassTemplateSpec->setSpecializationKind(
523 ExplicitInstantiation? TSK_ExplicitInstantiation
524 : TSK_ImplicitInstantiation);
525
526
527 bool Invalid = false;
528
529 // Enter the scope of this instantiation. We don't use
530 // PushDeclContext because we don't have a scope.
531 DeclContext *PreviousContext = CurContext;
532 CurContext = ClassTemplateSpec;
533
534 // Start the definition of this instantiation.
535 ClassTemplateSpec->startDefinition();
536
537 // FIXME: Create the injected-class-name for the
538 // instantiation. Should this be a typedef or something like it?
539
540 // Instantiate the base class specifiers.
541 if (InstantiateBaseSpecifiers(ClassTemplateSpec, Template))
542 Invalid = true;
543
544 // FIXME: Instantiate all of the members.
545
546 // Add any implicitly-declared members that we might need.
547 AddImplicitlyDeclaredMembersToClass(ClassTemplateSpec);
548
549 // Finish the definition of this instantiation.
550 // FIXME: ActOnFields does more checking, which we'll eventually need.
551 ClassTemplateSpec->completeDefinition(Context);
552
553 // Exit the scope of this instantiation.
554 CurContext = PreviousContext;
555
556 return Invalid;
557}