1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the C++ related Decl classes for templates.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/Expr.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/TypeLoc.h"
20 #include "clang/AST/ASTMutationListener.h"
21 #include "clang/Basic/IdentifierTable.h"
22 #include "llvm/ADT/STLExtras.h"
24 using namespace clang
;
26 //===----------------------------------------------------------------------===//
27 // TemplateParameterList Implementation
28 //===----------------------------------------------------------------------===//
30 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc
,
31 SourceLocation LAngleLoc
,
32 NamedDecl
**Params
, unsigned NumParams
,
33 SourceLocation RAngleLoc
)
34 : TemplateLoc(TemplateLoc
), LAngleLoc(LAngleLoc
), RAngleLoc(RAngleLoc
),
35 NumParams(NumParams
) {
36 for (unsigned Idx
= 0; Idx
< NumParams
; ++Idx
)
37 begin()[Idx
] = Params
[Idx
];
40 TemplateParameterList
*
41 TemplateParameterList::Create(const ASTContext
&C
, SourceLocation TemplateLoc
,
42 SourceLocation LAngleLoc
, NamedDecl
**Params
,
43 unsigned NumParams
, SourceLocation RAngleLoc
) {
44 unsigned Size
= sizeof(TemplateParameterList
)
45 + sizeof(NamedDecl
*) * NumParams
;
46 unsigned Align
= llvm::AlignOf
<TemplateParameterList
>::Alignment
;
47 void *Mem
= C
.Allocate(Size
, Align
);
48 return new (Mem
) TemplateParameterList(TemplateLoc
, LAngleLoc
, Params
,
49 NumParams
, RAngleLoc
);
52 unsigned TemplateParameterList::getMinRequiredArguments() const {
53 unsigned NumRequiredArgs
= 0;
54 for (iterator P
= const_cast<TemplateParameterList
*>(this)->begin(),
55 PEnd
= const_cast<TemplateParameterList
*>(this)->end();
57 if ((*P
)->isTemplateParameterPack()) {
58 if (NonTypeTemplateParmDecl
*NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(*P
))
59 if (NTTP
->isExpandedParameterPack()) {
60 NumRequiredArgs
+= NTTP
->getNumExpansionTypes();
67 if (TemplateTypeParmDecl
*TTP
= dyn_cast
<TemplateTypeParmDecl
>(*P
)) {
68 if (TTP
->hasDefaultArgument())
70 } else if (NonTypeTemplateParmDecl
*NTTP
71 = dyn_cast
<NonTypeTemplateParmDecl
>(*P
)) {
72 if (NTTP
->hasDefaultArgument())
74 } else if (cast
<TemplateTemplateParmDecl
>(*P
)->hasDefaultArgument())
80 return NumRequiredArgs
;
83 unsigned TemplateParameterList::getDepth() const {
87 const NamedDecl
*FirstParm
= getParam(0);
88 if (const TemplateTypeParmDecl
*TTP
89 = dyn_cast
<TemplateTypeParmDecl
>(FirstParm
))
90 return TTP
->getDepth();
91 else if (const NonTypeTemplateParmDecl
*NTTP
92 = dyn_cast
<NonTypeTemplateParmDecl
>(FirstParm
))
93 return NTTP
->getDepth();
95 return cast
<TemplateTemplateParmDecl
>(FirstParm
)->getDepth();
98 //===----------------------------------------------------------------------===//
99 // RedeclarableTemplateDecl Implementation
100 //===----------------------------------------------------------------------===//
102 RedeclarableTemplateDecl::CommonBase
*RedeclarableTemplateDecl::getCommonPtr() {
103 // Find the first declaration of this function template.
104 RedeclarableTemplateDecl
*First
= getCanonicalDecl();
106 if (First
->CommonOrPrev
.isNull()) {
107 CommonBase
*CommonPtr
= First
->newCommon(getASTContext());
108 First
->CommonOrPrev
= CommonPtr
;
109 CommonPtr
->Latest
= First
;
111 return First
->CommonOrPrev
.get
<CommonBase
*>();
115 RedeclarableTemplateDecl
*RedeclarableTemplateDecl::getCanonicalDeclImpl() {
116 RedeclarableTemplateDecl
*Tmpl
= this;
117 while (Tmpl
->getPreviousDeclaration())
118 Tmpl
= Tmpl
->getPreviousDeclaration();
122 void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
123 RedeclarableTemplateDecl
*Prev
) {
125 CommonBase
*Common
= Prev
->getCommonPtr();
126 Prev
= Common
->Latest
;
127 Common
->Latest
= this;
130 assert(CommonOrPrev
.is
<CommonBase
*>() && "Cannot reset TemplateDecl Prev");
134 RedeclarableTemplateDecl
*RedeclarableTemplateDecl::getNextRedeclaration() {
135 if (CommonOrPrev
.is
<RedeclarableTemplateDecl
*>())
136 return CommonOrPrev
.get
<RedeclarableTemplateDecl
*>();
137 CommonBase
*Common
= CommonOrPrev
.get
<CommonBase
*>();
138 return Common
? Common
->Latest
: this;
141 template <class EntryType
>
142 typename
RedeclarableTemplateDecl::SpecEntryTraits
<EntryType
>::DeclType
*
143 RedeclarableTemplateDecl::findSpecializationImpl(
144 llvm::FoldingSet
<EntryType
> &Specs
,
145 const TemplateArgument
*Args
, unsigned NumArgs
,
147 typedef SpecEntryTraits
<EntryType
> SETraits
;
148 llvm::FoldingSetNodeID ID
;
149 EntryType::Profile(ID
,Args
,NumArgs
, getASTContext());
150 EntryType
*Entry
= Specs
.FindNodeOrInsertPos(ID
, InsertPos
);
151 return Entry
? SETraits::getMostRecentDeclaration(Entry
) : 0;
154 //===----------------------------------------------------------------------===//
155 // FunctionTemplateDecl Implementation
156 //===----------------------------------------------------------------------===//
158 void FunctionTemplateDecl::DeallocateCommon(void *Ptr
) {
159 static_cast<Common
*>(Ptr
)->~Common();
162 FunctionTemplateDecl
*FunctionTemplateDecl::Create(ASTContext
&C
,
165 DeclarationName Name
,
166 TemplateParameterList
*Params
,
168 return new (C
) FunctionTemplateDecl(DC
, L
, Name
, Params
, Decl
);
171 RedeclarableTemplateDecl::CommonBase
*
172 FunctionTemplateDecl::newCommon(ASTContext
&C
) {
173 Common
*CommonPtr
= new (C
) Common
;
174 C
.AddDeallocation(DeallocateCommon
, CommonPtr
);
179 FunctionTemplateDecl::findSpecialization(const TemplateArgument
*Args
,
180 unsigned NumArgs
, void *&InsertPos
) {
181 return findSpecializationImpl(getSpecializations(), Args
, NumArgs
, InsertPos
);
184 //===----------------------------------------------------------------------===//
185 // ClassTemplateDecl Implementation
186 //===----------------------------------------------------------------------===//
188 void ClassTemplateDecl::DeallocateCommon(void *Ptr
) {
189 static_cast<Common
*>(Ptr
)->~Common();
192 ClassTemplateDecl
*ClassTemplateDecl::Create(ASTContext
&C
,
195 DeclarationName Name
,
196 TemplateParameterList
*Params
,
198 ClassTemplateDecl
*PrevDecl
) {
199 ClassTemplateDecl
*New
= new (C
) ClassTemplateDecl(DC
, L
, Name
, Params
, Decl
);
200 New
->setPreviousDeclaration(PrevDecl
);
204 void ClassTemplateDecl::LoadLazySpecializations() {
205 Common
*CommonPtr
= getCommonPtr();
206 if (CommonPtr
->LazySpecializations
) {
207 ASTContext
&Context
= getASTContext();
208 uint32_t *Specs
= CommonPtr
->LazySpecializations
;
209 CommonPtr
->LazySpecializations
= 0;
210 for (uint32_t I
= 0, N
= *Specs
++; I
!= N
; ++I
)
211 (void)Context
.getExternalSource()->GetExternalDecl(Specs
[I
]);
215 llvm::FoldingSet
<ClassTemplateSpecializationDecl
> &
216 ClassTemplateDecl::getSpecializations() {
217 LoadLazySpecializations();
218 return getCommonPtr()->Specializations
;
221 llvm::FoldingSet
<ClassTemplatePartialSpecializationDecl
> &
222 ClassTemplateDecl::getPartialSpecializations() {
223 LoadLazySpecializations();
224 return getCommonPtr()->PartialSpecializations
;
227 RedeclarableTemplateDecl::CommonBase
*
228 ClassTemplateDecl::newCommon(ASTContext
&C
) {
229 Common
*CommonPtr
= new (C
) Common
;
230 C
.AddDeallocation(DeallocateCommon
, CommonPtr
);
234 ClassTemplateSpecializationDecl
*
235 ClassTemplateDecl::findSpecialization(const TemplateArgument
*Args
,
236 unsigned NumArgs
, void *&InsertPos
) {
237 return findSpecializationImpl(getSpecializations(), Args
, NumArgs
, InsertPos
);
240 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl
*D
,
242 getSpecializations().InsertNode(D
, InsertPos
);
243 if (ASTMutationListener
*L
= getASTMutationListener())
244 L
->AddedCXXTemplateSpecialization(this, D
);
247 ClassTemplatePartialSpecializationDecl
*
248 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument
*Args
,
251 return findSpecializationImpl(getPartialSpecializations(), Args
, NumArgs
,
255 void ClassTemplateDecl::AddPartialSpecialization(
256 ClassTemplatePartialSpecializationDecl
*D
,
258 getPartialSpecializations().InsertNode(D
, InsertPos
);
259 if (ASTMutationListener
*L
= getASTMutationListener())
260 L
->AddedCXXTemplateSpecialization(this, D
);
263 void ClassTemplateDecl::getPartialSpecializations(
264 llvm::SmallVectorImpl
<ClassTemplatePartialSpecializationDecl
*> &PS
) {
265 llvm::FoldingSet
<ClassTemplatePartialSpecializationDecl
> &PartialSpecs
266 = getPartialSpecializations();
268 PS
.resize(PartialSpecs
.size());
269 for (llvm::FoldingSet
<ClassTemplatePartialSpecializationDecl
>::iterator
270 P
= PartialSpecs
.begin(), PEnd
= PartialSpecs
.end();
272 assert(!PS
[P
->getSequenceNumber()]);
273 PS
[P
->getSequenceNumber()] = P
->getMostRecentDeclaration();
277 ClassTemplatePartialSpecializationDecl
*
278 ClassTemplateDecl::findPartialSpecialization(QualType T
) {
279 ASTContext
&Context
= getASTContext();
280 typedef llvm::FoldingSet
<ClassTemplatePartialSpecializationDecl
>::iterator
281 partial_spec_iterator
;
282 for (partial_spec_iterator P
= getPartialSpecializations().begin(),
283 PEnd
= getPartialSpecializations().end();
285 if (Context
.hasSameType(P
->getInjectedSpecializationType(), T
))
286 return P
->getMostRecentDeclaration();
292 ClassTemplatePartialSpecializationDecl
*
293 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
294 ClassTemplatePartialSpecializationDecl
*D
) {
295 Decl
*DCanon
= D
->getCanonicalDecl();
296 for (llvm::FoldingSet
<ClassTemplatePartialSpecializationDecl
>::iterator
297 P
= getPartialSpecializations().begin(),
298 PEnd
= getPartialSpecializations().end();
300 if (P
->getInstantiatedFromMember()->getCanonicalDecl() == DCanon
)
301 return P
->getMostRecentDeclaration();
308 ClassTemplateDecl::getInjectedClassNameSpecialization() {
309 Common
*CommonPtr
= getCommonPtr();
310 if (!CommonPtr
->InjectedClassNameType
.isNull())
311 return CommonPtr
->InjectedClassNameType
;
313 // C++0x [temp.dep.type]p2:
314 // The template argument list of a primary template is a template argument
315 // list in which the nth template argument has the value of the nth template
316 // parameter of the class template. If the nth template parameter is a
317 // template parameter pack (14.5.3), the nth template argument is a pack
318 // expansion (14.5.3) whose pattern is the name of the template parameter
320 ASTContext
&Context
= getASTContext();
321 TemplateParameterList
*Params
= getTemplateParameters();
322 llvm::SmallVector
<TemplateArgument
, 16> TemplateArgs
;
323 TemplateArgs
.reserve(Params
->size());
324 for (TemplateParameterList::iterator Param
= Params
->begin(),
325 ParamEnd
= Params
->end();
326 Param
!= ParamEnd
; ++Param
) {
327 TemplateArgument Arg
;
328 if (TemplateTypeParmDecl
*TTP
= dyn_cast
<TemplateTypeParmDecl
>(*Param
)) {
329 QualType ArgType
= Context
.getTypeDeclType(TTP
);
330 if (TTP
->isParameterPack())
331 ArgType
= Context
.getPackExpansionType(ArgType
,
332 llvm::Optional
<unsigned>());
334 Arg
= TemplateArgument(ArgType
);
335 } else if (NonTypeTemplateParmDecl
*NTTP
=
336 dyn_cast
<NonTypeTemplateParmDecl
>(*Param
)) {
337 Expr
*E
= new (Context
) DeclRefExpr(NTTP
,
338 NTTP
->getType().getNonLValueExprType(Context
),
339 Expr::getValueKindForType(NTTP
->getType()),
340 NTTP
->getLocation());
342 if (NTTP
->isParameterPack())
343 E
= new (Context
) PackExpansionExpr(Context
.DependentTy
, E
,
345 llvm::Optional
<unsigned>());
346 Arg
= TemplateArgument(E
);
348 TemplateTemplateParmDecl
*TTP
= cast
<TemplateTemplateParmDecl
>(*Param
);
349 if (TTP
->isParameterPack())
350 Arg
= TemplateArgument(TemplateName(TTP
), llvm::Optional
<unsigned>());
352 Arg
= TemplateArgument(TemplateName(TTP
));
355 if ((*Param
)->isTemplateParameterPack())
356 Arg
= TemplateArgument::CreatePackCopy(Context
, &Arg
, 1);
358 TemplateArgs
.push_back(Arg
);
361 CommonPtr
->InjectedClassNameType
362 = Context
.getTemplateSpecializationType(TemplateName(this),
364 TemplateArgs
.size());
365 return CommonPtr
->InjectedClassNameType
;
368 //===----------------------------------------------------------------------===//
369 // TemplateTypeParm Allocation/Deallocation Method Implementations
370 //===----------------------------------------------------------------------===//
372 TemplateTypeParmDecl
*
373 TemplateTypeParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
374 SourceLocation L
, unsigned D
, unsigned P
,
375 IdentifierInfo
*Id
, bool Typename
,
376 bool ParameterPack
) {
377 QualType Type
= C
.getTemplateTypeParmType(D
, P
, ParameterPack
, Id
);
378 return new (C
) TemplateTypeParmDecl(DC
, L
, Id
, Typename
, Type
, ParameterPack
);
381 TemplateTypeParmDecl
*
382 TemplateTypeParmDecl::Create(const ASTContext
&C
, EmptyShell Empty
) {
383 return new (C
) TemplateTypeParmDecl(0, SourceLocation(), 0, false,
387 SourceLocation
TemplateTypeParmDecl::getDefaultArgumentLoc() const {
388 return DefaultArgument
->getTypeLoc().getSourceRange().getBegin();
391 unsigned TemplateTypeParmDecl::getDepth() const {
392 return TypeForDecl
->getAs
<TemplateTypeParmType
>()->getDepth();
395 unsigned TemplateTypeParmDecl::getIndex() const {
396 return TypeForDecl
->getAs
<TemplateTypeParmType
>()->getIndex();
399 //===----------------------------------------------------------------------===//
400 // NonTypeTemplateParmDecl Method Implementations
401 //===----------------------------------------------------------------------===//
403 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext
*DC
,
404 SourceLocation L
, unsigned D
,
405 unsigned P
, IdentifierInfo
*Id
,
407 TypeSourceInfo
*TInfo
,
408 const QualType
*ExpandedTypes
,
409 unsigned NumExpandedTypes
,
410 TypeSourceInfo
**ExpandedTInfos
)
411 : DeclaratorDecl(NonTypeTemplateParm
, DC
, L
, Id
, T
, TInfo
),
412 TemplateParmPosition(D
, P
), DefaultArgumentAndInherited(0, false),
413 ParameterPack(true), ExpandedParameterPack(true),
414 NumExpandedTypes(NumExpandedTypes
)
416 if (ExpandedTypes
&& ExpandedTInfos
) {
417 void **TypesAndInfos
= reinterpret_cast<void **>(this + 1);
418 for (unsigned I
= 0; I
!= NumExpandedTypes
; ++I
) {
419 TypesAndInfos
[2*I
] = ExpandedTypes
[I
].getAsOpaquePtr();
420 TypesAndInfos
[2*I
+ 1] = ExpandedTInfos
[I
];
425 NonTypeTemplateParmDecl
*
426 NonTypeTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
427 SourceLocation L
, unsigned D
, unsigned P
,
428 IdentifierInfo
*Id
, QualType T
,
429 bool ParameterPack
, TypeSourceInfo
*TInfo
) {
430 return new (C
) NonTypeTemplateParmDecl(DC
, L
, D
, P
, Id
, T
, ParameterPack
,
434 NonTypeTemplateParmDecl
*
435 NonTypeTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
436 SourceLocation L
, unsigned D
, unsigned P
,
437 IdentifierInfo
*Id
, QualType T
,
438 TypeSourceInfo
*TInfo
,
439 const QualType
*ExpandedTypes
,
440 unsigned NumExpandedTypes
,
441 TypeSourceInfo
**ExpandedTInfos
) {
442 unsigned Size
= sizeof(NonTypeTemplateParmDecl
)
443 + NumExpandedTypes
* 2 * sizeof(void*);
444 void *Mem
= C
.Allocate(Size
);
445 return new (Mem
) NonTypeTemplateParmDecl(DC
, L
, D
, P
, Id
, T
, TInfo
,
446 ExpandedTypes
, NumExpandedTypes
,
450 SourceLocation
NonTypeTemplateParmDecl::getInnerLocStart() const {
451 SourceLocation Start
= getTypeSpecStartLoc();
452 if (Start
.isInvalid())
453 Start
= getLocation();
457 SourceRange
NonTypeTemplateParmDecl::getSourceRange() const {
458 return SourceRange(getOuterLocStart(), getLocation());
461 SourceLocation
NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
462 return hasDefaultArgument()
463 ? getDefaultArgument()->getSourceRange().getBegin()
467 //===----------------------------------------------------------------------===//
468 // TemplateTemplateParmDecl Method Implementations
469 //===----------------------------------------------------------------------===//
471 TemplateTemplateParmDecl
*
472 TemplateTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
473 SourceLocation L
, unsigned D
, unsigned P
,
474 bool ParameterPack
, IdentifierInfo
*Id
,
475 TemplateParameterList
*Params
) {
476 return new (C
) TemplateTemplateParmDecl(DC
, L
, D
, P
, ParameterPack
, Id
,
480 //===----------------------------------------------------------------------===//
481 // TemplateArgumentList Implementation
482 //===----------------------------------------------------------------------===//
483 TemplateArgumentList
*
484 TemplateArgumentList::CreateCopy(ASTContext
&Context
,
485 const TemplateArgument
*Args
,
487 std::size_t Size
= sizeof(TemplateArgumentList
)
488 + NumArgs
* sizeof(TemplateArgument
);
489 void *Mem
= Context
.Allocate(Size
);
490 TemplateArgument
*StoredArgs
491 = reinterpret_cast<TemplateArgument
*>(
492 static_cast<TemplateArgumentList
*>(Mem
) + 1);
493 std::uninitialized_copy(Args
, Args
+ NumArgs
, StoredArgs
);
494 return new (Mem
) TemplateArgumentList(StoredArgs
, NumArgs
, true);
497 //===----------------------------------------------------------------------===//
498 // ClassTemplateSpecializationDecl Implementation
499 //===----------------------------------------------------------------------===//
500 ClassTemplateSpecializationDecl::
501 ClassTemplateSpecializationDecl(ASTContext
&Context
, Kind DK
, TagKind TK
,
502 DeclContext
*DC
, SourceLocation L
,
503 ClassTemplateDecl
*SpecializedTemplate
,
504 const TemplateArgument
*Args
,
506 ClassTemplateSpecializationDecl
*PrevDecl
)
507 : CXXRecordDecl(DK
, TK
, DC
, L
,
508 SpecializedTemplate
->getIdentifier(),
510 SpecializedTemplate(SpecializedTemplate
),
512 TemplateArgs(TemplateArgumentList::CreateCopy(Context
, Args
, NumArgs
)),
513 SpecializationKind(TSK_Undeclared
) {
516 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK
)
517 : CXXRecordDecl(DK
, TTK_Struct
, 0, SourceLocation(), 0, 0),
519 SpecializationKind(TSK_Undeclared
) {
522 ClassTemplateSpecializationDecl
*
523 ClassTemplateSpecializationDecl::Create(ASTContext
&Context
, TagKind TK
,
524 DeclContext
*DC
, SourceLocation L
,
525 ClassTemplateDecl
*SpecializedTemplate
,
526 const TemplateArgument
*Args
,
528 ClassTemplateSpecializationDecl
*PrevDecl
) {
529 ClassTemplateSpecializationDecl
*Result
530 = new (Context
)ClassTemplateSpecializationDecl(Context
,
531 ClassTemplateSpecialization
,
536 Context
.getTypeDeclType(Result
, PrevDecl
);
540 ClassTemplateSpecializationDecl
*
541 ClassTemplateSpecializationDecl::Create(ASTContext
&Context
, EmptyShell Empty
) {
543 new (Context
)ClassTemplateSpecializationDecl(ClassTemplateSpecialization
);
547 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string
&S
,
548 const PrintingPolicy
&Policy
,
549 bool Qualified
) const {
550 NamedDecl::getNameForDiagnostic(S
, Policy
, Qualified
);
552 const TemplateArgumentList
&TemplateArgs
= getTemplateArgs();
553 S
+= TemplateSpecializationType::PrintTemplateArgumentList(
560 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
561 if (SpecializedPartialSpecialization
*PartialSpec
562 = SpecializedTemplate
.dyn_cast
<SpecializedPartialSpecialization
*>())
563 return PartialSpec
->PartialSpecialization
->getSpecializedTemplate();
564 return SpecializedTemplate
.get
<ClassTemplateDecl
*>();
567 //===----------------------------------------------------------------------===//
568 // ClassTemplatePartialSpecializationDecl Implementation
569 //===----------------------------------------------------------------------===//
570 ClassTemplatePartialSpecializationDecl
*
571 ClassTemplatePartialSpecializationDecl::
572 Create(ASTContext
&Context
, TagKind TK
,DeclContext
*DC
, SourceLocation L
,
573 TemplateParameterList
*Params
,
574 ClassTemplateDecl
*SpecializedTemplate
,
575 const TemplateArgument
*Args
,
577 const TemplateArgumentListInfo
&ArgInfos
,
578 QualType CanonInjectedType
,
579 ClassTemplatePartialSpecializationDecl
*PrevDecl
,
580 unsigned SequenceNumber
) {
581 unsigned N
= ArgInfos
.size();
582 TemplateArgumentLoc
*ClonedArgs
= new (Context
) TemplateArgumentLoc
[N
];
583 for (unsigned I
= 0; I
!= N
; ++I
)
584 ClonedArgs
[I
] = ArgInfos
[I
];
586 ClassTemplatePartialSpecializationDecl
*Result
587 = new (Context
)ClassTemplatePartialSpecializationDecl(Context
, TK
,
594 Result
->setSpecializationKind(TSK_ExplicitSpecialization
);
596 Context
.getInjectedClassNameType(Result
, CanonInjectedType
);
600 ClassTemplatePartialSpecializationDecl
*
601 ClassTemplatePartialSpecializationDecl::Create(ASTContext
&Context
,
603 return new (Context
)ClassTemplatePartialSpecializationDecl();
606 //===----------------------------------------------------------------------===//
607 // FriendTemplateDecl Implementation
608 //===----------------------------------------------------------------------===//
610 FriendTemplateDecl
*FriendTemplateDecl::Create(ASTContext
&Context
,
614 TemplateParameterList
**Params
,
616 SourceLocation FLoc
) {
617 FriendTemplateDecl
*Result
618 = new (Context
) FriendTemplateDecl(DC
, L
, NParams
, Params
, Friend
, FLoc
);
622 FriendTemplateDecl
*FriendTemplateDecl::Create(ASTContext
&Context
,
624 return new (Context
) FriendTemplateDecl(Empty
);