clang  8.0.0svn
DeclTemplate.cpp
Go to the documentation of this file.
1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
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 //
10 // This file implements the C++ related Decl classes for templates.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/DeclTemplate.h"
15 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/Expr.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/AST/TemplateName.h"
23 #include "clang/AST/Type.h"
24 #include "clang/AST/TypeLoc.h"
25 #include "clang/Basic/Builtins.h"
26 #include "clang/Basic/LLVM.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/FoldingSet.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/PointerUnion.h"
32 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdint>
38 #include <memory>
39 #include <utility>
40 
41 using namespace clang;
42 
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
46 
48  SourceLocation LAngleLoc,
49  ArrayRef<NamedDecl *> Params,
50  SourceLocation RAngleLoc,
51  Expr *RequiresClause)
52  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
53  NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
54  HasRequiresClause(static_cast<bool>(RequiresClause)) {
55  for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
56  NamedDecl *P = Params[Idx];
57  begin()[Idx] = P;
58 
59  if (!P->isTemplateParameterPack()) {
60  if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
61  if (NTTP->getType()->containsUnexpandedParameterPack())
62  ContainsUnexpandedParameterPack = true;
63 
64  if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
65  if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
66  ContainsUnexpandedParameterPack = true;
67 
68  // FIXME: If a default argument contains an unexpanded parameter pack, the
69  // template parameter list does too.
70  }
71  }
72  if (RequiresClause) {
73  *getTrailingObjects<Expr *>() = RequiresClause;
74  }
75 }
76 
79  SourceLocation LAngleLoc,
80  ArrayRef<NamedDecl *> Params,
81  SourceLocation RAngleLoc, Expr *RequiresClause) {
82  void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
83  Params.size(), RequiresClause ? 1u : 0u),
84  alignof(TemplateParameterList));
85  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
86  RAngleLoc, RequiresClause);
87 }
88 
90  unsigned NumRequiredArgs = 0;
91  for (const NamedDecl *P : asArray()) {
92  if (P->isTemplateParameterPack()) {
93  if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
94  if (NTTP->isExpandedParameterPack()) {
95  NumRequiredArgs += NTTP->getNumExpansionTypes();
96  continue;
97  }
98 
99  break;
100  }
101 
102  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
103  if (TTP->hasDefaultArgument())
104  break;
105  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
106  if (NTTP->hasDefaultArgument())
107  break;
108  } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
109  break;
110 
111  ++NumRequiredArgs;
112  }
113 
114  return NumRequiredArgs;
115 }
116 
118  if (size() == 0)
119  return 0;
120 
121  const NamedDecl *FirstParm = getParam(0);
122  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
123  return TTP->getDepth();
124  else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
125  return NTTP->getDepth();
126  else
127  return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
128 }
129 
131  DeclContext *Owner) {
132  for (NamedDecl *P : *Params) {
133  P->setDeclContext(Owner);
134 
135  if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
136  AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
137  }
138 }
139 
140 namespace clang {
141 
143  return new (C) char[sizeof(void*) * 2];
144 }
145 
146 } // namespace clang
147 
148 //===----------------------------------------------------------------------===//
149 // RedeclarableTemplateDecl Implementation
150 //===----------------------------------------------------------------------===//
151 
153  if (Common)
154  return Common;
155 
156  // Walk the previous-declaration chain until we either find a declaration
157  // with a common pointer or we run out of previous declarations.
159  for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
160  Prev = Prev->getPreviousDecl()) {
161  if (Prev->Common) {
162  Common = Prev->Common;
163  break;
164  }
165 
166  PrevDecls.push_back(Prev);
167  }
168 
169  // If we never found a common pointer, allocate one now.
170  if (!Common) {
171  // FIXME: If any of the declarations is from an AST file, we probably
172  // need an update record to add the common data.
173 
174  Common = newCommon(getASTContext());
175  }
176 
177  // Update any previous declarations we saw with the common pointer.
178  for (const RedeclarableTemplateDecl *Prev : PrevDecls)
179  Prev->Common = Common;
180 
181  return Common;
182 }
183 
185  // Grab the most recent declaration to ensure we've loaded any lazy
186  // redeclarations of this template.
187  CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
188  if (CommonBasePtr->LazySpecializations) {
189  ASTContext &Context = getASTContext();
190  uint32_t *Specs = CommonBasePtr->LazySpecializations;
191  CommonBasePtr->LazySpecializations = nullptr;
192  for (uint32_t I = 0, N = *Specs++; I != N; ++I)
193  (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
194  }
195 }
196 
197 template<class EntryType>
200  llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
201  void *&InsertPos) {
202  using SETraits = SpecEntryTraits<EntryType>;
203 
204  llvm::FoldingSetNodeID ID;
205  EntryType::Profile(ID, Args, getASTContext());
206  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
207  return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
208 }
209 
210 template<class Derived, class EntryType>
212  llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
213  void *InsertPos) {
214  using SETraits = SpecEntryTraits<EntryType>;
215 
216  if (InsertPos) {
217 #ifndef NDEBUG
218  void *CorrectInsertPos;
219  assert(!findSpecializationImpl(Specializations,
220  SETraits::getTemplateArgs(Entry),
221  CorrectInsertPos) &&
222  InsertPos == CorrectInsertPos &&
223  "given incorrect InsertPos for specialization");
224 #endif
225  Specializations.InsertNode(Entry, InsertPos);
226  } else {
227  EntryType *Existing = Specializations.GetOrInsertNode(Entry);
228  (void)Existing;
229  assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
230  "non-canonical specialization?");
231  }
232 
233  if (ASTMutationListener *L = getASTMutationListener())
234  L->AddedCXXTemplateSpecialization(cast<Derived>(this),
235  SETraits::getDecl(Entry));
236 }
237 
238 //===----------------------------------------------------------------------===//
239 // FunctionTemplateDecl Implementation
240 //===----------------------------------------------------------------------===//
241 
243  DeclContext *DC,
244  SourceLocation L,
245  DeclarationName Name,
246  TemplateParameterList *Params,
247  NamedDecl *Decl) {
248  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
249  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
250 }
251 
253  unsigned ID) {
254  return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
255  DeclarationName(), nullptr, nullptr);
256 }
257 
260  auto *CommonPtr = new (C) Common;
261  C.addDestruction(CommonPtr);
262  return CommonPtr;
263 }
264 
266  loadLazySpecializationsImpl();
267 }
268 
269 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
271  LoadLazySpecializations();
272  return getCommonPtr()->Specializations;
273 }
274 
275 FunctionDecl *
277  void *&InsertPos) {
278  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
279 }
280 
282  FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
283  addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
284  InsertPos);
285 }
286 
288  TemplateParameterList *Params = getTemplateParameters();
289  Common *CommonPtr = getCommonPtr();
290  if (!CommonPtr->InjectedArgs) {
291  auto &Context = getASTContext();
293  Context.getInjectedTemplateArgs(Params, TemplateArgs);
294  CommonPtr->InjectedArgs =
295  new (Context) TemplateArgument[TemplateArgs.size()];
296  std::copy(TemplateArgs.begin(), TemplateArgs.end(),
297  CommonPtr->InjectedArgs);
298  }
299 
300  return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
301 }
302 
305 
306  // If we haven't created a common pointer yet, then it can just be created
307  // with the usual method.
308  if (!Base::Common)
309  return;
310 
311  Common *ThisCommon = static_cast<Common *>(Base::Common);
312  Common *PrevCommon = nullptr;
314  for (; Prev; Prev = Prev->getPreviousDecl()) {
315  if (Prev->Base::Common) {
316  PrevCommon = static_cast<Common *>(Prev->Base::Common);
317  break;
318  }
319  PreviousDecls.push_back(Prev);
320  }
321 
322  // If the previous redecl chain hasn't created a common pointer yet, then just
323  // use this common pointer.
324  if (!PrevCommon) {
325  for (auto *D : PreviousDecls)
326  D->Base::Common = ThisCommon;
327  return;
328  }
329 
330  // Ensure we don't leak any important state.
331  assert(ThisCommon->Specializations.size() == 0 &&
332  "Can't merge incompatible declarations!");
333 
334  Base::Common = PrevCommon;
335 }
336 
337 //===----------------------------------------------------------------------===//
338 // ClassTemplateDecl Implementation
339 //===----------------------------------------------------------------------===//
340 
342  DeclContext *DC,
343  SourceLocation L,
344  DeclarationName Name,
345  TemplateParameterList *Params,
346  NamedDecl *Decl,
347  Expr *AssociatedConstraints) {
348  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
349 
350  if (!AssociatedConstraints) {
351  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
352  }
353 
354  auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
355  auto *const New =
356  new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
357  New->setAssociatedConstraints(AssociatedConstraints);
358  return New;
359 }
360 
362  unsigned ID) {
363  return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
364  DeclarationName(), nullptr, nullptr);
365 }
366 
368  loadLazySpecializationsImpl();
369 }
370 
371 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
373  LoadLazySpecializations();
374  return getCommonPtr()->Specializations;
375 }
376 
377 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
379  LoadLazySpecializations();
380  return getCommonPtr()->PartialSpecializations;
381 }
382 
385  auto *CommonPtr = new (C) Common;
386  C.addDestruction(CommonPtr);
387  return CommonPtr;
388 }
389 
392  void *&InsertPos) {
393  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
394 }
395 
397  void *InsertPos) {
398  addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
399 }
400 
403  void *&InsertPos) {
404  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
405 }
406 
409  void *InsertPos) {
410  if (InsertPos)
411  getPartialSpecializations().InsertNode(D, InsertPos);
412  else {
414  = getPartialSpecializations().GetOrInsertNode(D);
415  (void)Existing;
416  assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
417  }
418 
419  if (ASTMutationListener *L = getASTMutationListener())
420  L->AddedCXXTemplateSpecialization(this, D);
421 }
422 
425  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
426  = getPartialSpecializations();
427  PS.clear();
428  PS.reserve(PartialSpecs.size());
429  for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
430  PS.push_back(P.getMostRecentDecl());
431 }
432 
435  ASTContext &Context = getASTContext();
437  getPartialSpecializations()) {
438  if (Context.hasSameType(P.getInjectedSpecializationType(), T))
439  return P.getMostRecentDecl();
440  }
441 
442  return nullptr;
443 }
444 
448  Decl *DCanon = D->getCanonicalDecl();
449  for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
450  if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
451  return P.getMostRecentDecl();
452  }
453 
454  return nullptr;
455 }
456 
457 QualType
459  Common *CommonPtr = getCommonPtr();
460  if (!CommonPtr->InjectedClassNameType.isNull())
461  return CommonPtr->InjectedClassNameType;
462 
463  // C++0x [temp.dep.type]p2:
464  // The template argument list of a primary template is a template argument
465  // list in which the nth template argument has the value of the nth template
466  // parameter of the class template. If the nth template parameter is a
467  // template parameter pack (14.5.3), the nth template argument is a pack
468  // expansion (14.5.3) whose pattern is the name of the template parameter
469  // pack.
470  ASTContext &Context = getASTContext();
471  TemplateParameterList *Params = getTemplateParameters();
473  Context.getInjectedTemplateArgs(Params, TemplateArgs);
474  CommonPtr->InjectedClassNameType
476  TemplateArgs);
477  return CommonPtr->InjectedClassNameType;
478 }
479 
480 //===----------------------------------------------------------------------===//
481 // TemplateTypeParm Allocation/Deallocation Method Implementations
482 //===----------------------------------------------------------------------===//
483 
486  SourceLocation KeyLoc, SourceLocation NameLoc,
487  unsigned D, unsigned P, IdentifierInfo *Id,
488  bool Typename, bool ParameterPack) {
489  auto *TTPDecl =
490  new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
491  QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
492  TTPDecl->setTypeForDecl(TTPType.getTypePtr());
493  return TTPDecl;
494 }
495 
498  return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
499  SourceLocation(), nullptr, false);
500 }
501 
503  return hasDefaultArgument()
504  ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
505  : SourceLocation();
506 }
507 
509  if (hasDefaultArgument() && !defaultArgumentWasInherited())
510  return SourceRange(getBeginLoc(),
511  getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
512  else
513  return TypeDecl::getSourceRange();
514 }
515 
517  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
518 }
519 
521  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
522 }
523 
525  return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
526 }
527 
528 //===----------------------------------------------------------------------===//
529 // NonTypeTemplateParmDecl Method Implementations
530 //===----------------------------------------------------------------------===//
531 
532 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
533  DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
534  unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
535  ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
536  : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
537  TemplateParmPosition(D, P), ParameterPack(true),
538  ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
539  if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
540  auto TypesAndInfos =
541  getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
542  for (unsigned I = 0; I != NumExpandedTypes; ++I) {
543  new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
544  TypesAndInfos[I].second = ExpandedTInfos[I];
545  }
546  }
547 }
548 
551  SourceLocation StartLoc, SourceLocation IdLoc,
552  unsigned D, unsigned P, IdentifierInfo *Id,
553  QualType T, bool ParameterPack,
554  TypeSourceInfo *TInfo) {
555  return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
556  T, ParameterPack, TInfo);
557 }
558 
560  const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
561  SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
562  QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
563  ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
564  return new (C, DC,
565  additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
566  ExpandedTypes.size()))
567  NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
568  ExpandedTypes, ExpandedTInfos);
569 }
570 
573  return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
574  SourceLocation(), 0, 0, nullptr,
575  QualType(), false, nullptr);
576 }
577 
580  unsigned NumExpandedTypes) {
581  auto *NTTP =
582  new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
583  NumExpandedTypes))
585  0, 0, nullptr, QualType(), nullptr, None,
586  None);
587  NTTP->NumExpandedTypes = NumExpandedTypes;
588  return NTTP;
589 }
590 
592  if (hasDefaultArgument() && !defaultArgumentWasInherited())
593  return SourceRange(getOuterLocStart(),
594  getDefaultArgument()->getSourceRange().getEnd());
596 }
597 
599  return hasDefaultArgument()
600  ? getDefaultArgument()->getSourceRange().getBegin()
601  : SourceLocation();
602 }
603 
604 //===----------------------------------------------------------------------===//
605 // TemplateTemplateParmDecl Method Implementations
606 //===----------------------------------------------------------------------===//
607 
608 void TemplateTemplateParmDecl::anchor() {}
609 
610 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
611  DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
614  : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
615  TemplateParmPosition(D, P), ParameterPack(true),
616  ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
617  if (!Expansions.empty())
618  std::uninitialized_copy(Expansions.begin(), Expansions.end(),
619  getTrailingObjects<TemplateParameterList *>());
620 }
621 
624  SourceLocation L, unsigned D, unsigned P,
625  bool ParameterPack, IdentifierInfo *Id,
626  TemplateParameterList *Params) {
627  return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
628  Params);
629 }
630 
633  SourceLocation L, unsigned D, unsigned P,
634  IdentifierInfo *Id,
635  TemplateParameterList *Params,
637  return new (C, DC,
638  additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
639  TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
640 }
641 
644  return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
645  false, nullptr, nullptr);
646 }
647 
650  unsigned NumExpansions) {
651  auto *TTP =
652  new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
653  TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
654  nullptr, None);
655  TTP->NumExpandedParams = NumExpansions;
656  return TTP;
657 }
658 
660  return hasDefaultArgument() ? getDefaultArgument().getLocation()
661  : SourceLocation();
662 }
663 
665  const ASTContext &C, const TemplateArgumentLoc &DefArg) {
666  if (DefArg.getArgument().isNull())
667  DefaultArgument.set(nullptr);
668  else
669  DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
670 }
671 
672 //===----------------------------------------------------------------------===//
673 // TemplateArgumentList Implementation
674 //===----------------------------------------------------------------------===//
675 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
676  : Arguments(getTrailingObjects<TemplateArgument>()),
677  NumArguments(Args.size()) {
678  std::uninitialized_copy(Args.begin(), Args.end(),
679  getTrailingObjects<TemplateArgument>());
680 }
681 
685  void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
686  return new (Mem) TemplateArgumentList(Args);
687 }
688 
691  FunctionTemplateDecl *Template,
693  const TemplateArgumentList *TemplateArgs,
694  const TemplateArgumentListInfo *TemplateArgsAsWritten,
695  SourceLocation POI) {
696  const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
697  if (TemplateArgsAsWritten)
698  ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
699  *TemplateArgsAsWritten);
700 
701  return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
702  TemplateArgs,
703  ArgsAsWritten,
704  POI);
705 }
706 
707 //===----------------------------------------------------------------------===//
708 // TemplateDecl Implementation
709 //===----------------------------------------------------------------------===//
710 
711 void TemplateDecl::anchor() {}
712 
713 //===----------------------------------------------------------------------===//
714 // ClassTemplateSpecializationDecl Implementation
715 //===----------------------------------------------------------------------===//
716 
719  DeclContext *DC, SourceLocation StartLoc,
720  SourceLocation IdLoc,
721  ClassTemplateDecl *SpecializedTemplate,
724  : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
725  SpecializedTemplate->getIdentifier(), PrevDecl),
726  SpecializedTemplate(SpecializedTemplate),
727  TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
728  SpecializationKind(TSK_Undeclared) {
729 }
730 
732  Kind DK)
733  : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
734  SourceLocation(), nullptr, nullptr),
735  SpecializationKind(TSK_Undeclared) {}
736 
739  DeclContext *DC,
740  SourceLocation StartLoc,
741  SourceLocation IdLoc,
742  ClassTemplateDecl *SpecializedTemplate,
745  auto *Result =
746  new (Context, DC) ClassTemplateSpecializationDecl(
747  Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
748  SpecializedTemplate, Args, PrevDecl);
749  Result->setMayHaveOutOfDateDef(false);
750 
751  Context.getTypeDeclType(Result, PrevDecl);
752  return Result;
753 }
754 
757  unsigned ID) {
758  auto *Result =
759  new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
760  Result->setMayHaveOutOfDateDef(false);
761  return Result;
762 }
763 
765  raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
766  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
767 
768  const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
769  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
770  PS ? PS->getTemplateArgsAsWritten() : nullptr) {
771  printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
772  } else {
773  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
774  printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
775  }
776 }
777 
780  if (const auto *PartialSpec =
781  SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
782  return PartialSpec->PartialSpecialization->getSpecializedTemplate();
783  return SpecializedTemplate.get<ClassTemplateDecl*>();
784 }
785 
788  if (ExplicitInfo) {
790  if (Begin.isValid()) {
791  // Here we have an explicit (partial) specialization or instantiation.
795  if (getExternLoc().isValid())
796  Begin = getExternLoc();
798  if (End.isInvalid())
800  return SourceRange(Begin, End);
801  }
802  // An implicit instantiation of a class template partial specialization
803  // uses ExplicitInfo to record the TypeAsWritten, but the source
804  // locations should be retrieved from the instantiation pattern.
806  auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
807  CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
808  assert(inst_from != nullptr);
809  return inst_from->getSourceRange();
810  }
811  else {
812  // No explicit info available.
813  llvm::PointerUnion<ClassTemplateDecl *,
815  inst_from = getInstantiatedFrom();
816  if (inst_from.isNull())
818  if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
819  return ctd->getSourceRange();
820  return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
821  ->getSourceRange();
822  }
823 }
824 
825 //===----------------------------------------------------------------------===//
826 // ClassTemplatePartialSpecializationDecl Implementation
827 //===----------------------------------------------------------------------===//
828 void ClassTemplatePartialSpecializationDecl::anchor() {}
829 
830 ClassTemplatePartialSpecializationDecl::
831 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
832  DeclContext *DC,
833  SourceLocation StartLoc,
834  SourceLocation IdLoc,
835  TemplateParameterList *Params,
836  ClassTemplateDecl *SpecializedTemplate,
838  const ASTTemplateArgumentListInfo *ArgInfos,
841  ClassTemplatePartialSpecialization,
842  TK, DC, StartLoc, IdLoc,
843  SpecializedTemplate, Args, PrevDecl),
844  TemplateParams(Params), ArgsAsWritten(ArgInfos),
845  InstantiatedFromMember(nullptr, false) {
846  AdoptTemplateParameterList(Params, this);
847 }
848 
852  SourceLocation StartLoc, SourceLocation IdLoc,
853  TemplateParameterList *Params,
854  ClassTemplateDecl *SpecializedTemplate,
856  const TemplateArgumentListInfo &ArgInfos,
857  QualType CanonInjectedType,
859  const ASTTemplateArgumentListInfo *ASTArgInfos =
860  ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
861 
862  auto *Result = new (Context, DC)
863  ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
864  Params, SpecializedTemplate, Args,
865  ASTArgInfos, PrevDecl);
866  Result->setSpecializationKind(TSK_ExplicitSpecialization);
867  Result->setMayHaveOutOfDateDef(false);
868 
869  Context.getInjectedClassNameType(Result, CanonInjectedType);
870  return Result;
871 }
872 
875  unsigned ID) {
877  Result->setMayHaveOutOfDateDef(false);
878  return Result;
879 }
880 
881 //===----------------------------------------------------------------------===//
882 // FriendTemplateDecl Implementation
883 //===----------------------------------------------------------------------===//
884 
885 void FriendTemplateDecl::anchor() {}
886 
889  SourceLocation L,
891  FriendUnion Friend, SourceLocation FLoc) {
892  return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
893 }
894 
896  unsigned ID) {
897  return new (C, ID) FriendTemplateDecl(EmptyShell());
898 }
899 
900 //===----------------------------------------------------------------------===//
901 // TypeAliasTemplateDecl Implementation
902 //===----------------------------------------------------------------------===//
903 
905  DeclContext *DC,
906  SourceLocation L,
907  DeclarationName Name,
908  TemplateParameterList *Params,
909  NamedDecl *Decl) {
910  AdoptTemplateParameterList(Params, DC);
911  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
912 }
913 
915  unsigned ID) {
916  return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
917  DeclarationName(), nullptr, nullptr);
918 }
919 
922  auto *CommonPtr = new (C) Common;
923  C.addDestruction(CommonPtr);
924  return CommonPtr;
925 }
926 
927 //===----------------------------------------------------------------------===//
928 // ClassScopeFunctionSpecializationDecl Implementation
929 //===----------------------------------------------------------------------===//
930 
931 void ClassScopeFunctionSpecializationDecl::anchor() {}
932 
935  unsigned ID) {
937  nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
938 }
939 
940 //===----------------------------------------------------------------------===//
941 // VarTemplateDecl Implementation
942 //===----------------------------------------------------------------------===//
943 
945  VarTemplateDecl *CurD = this;
946  while (CurD) {
947  if (CurD->isThisDeclarationADefinition())
948  return CurD;
949  CurD = CurD->getPreviousDecl();
950  }
951  return nullptr;
952 }
953 
956  TemplateParameterList *Params,
957  VarDecl *Decl) {
958  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
959 }
960 
962  unsigned ID) {
963  return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
964  DeclarationName(), nullptr, nullptr);
965 }
966 
968  loadLazySpecializationsImpl();
969 }
970 
971 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
973  LoadLazySpecializations();
974  return getCommonPtr()->Specializations;
975 }
976 
977 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
979  LoadLazySpecializations();
980  return getCommonPtr()->PartialSpecializations;
981 }
982 
985  auto *CommonPtr = new (C) Common;
986  C.addDestruction(CommonPtr);
987  return CommonPtr;
988 }
989 
992  void *&InsertPos) {
993  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
994 }
995 
997  void *InsertPos) {
998  addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
999 }
1000 
1003  void *&InsertPos) {
1004  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1005 }
1006 
1008  VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1009  if (InsertPos)
1010  getPartialSpecializations().InsertNode(D, InsertPos);
1011  else {
1013  getPartialSpecializations().GetOrInsertNode(D);
1014  (void)Existing;
1015  assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1016  }
1017 
1019  L->AddedCXXTemplateSpecialization(this, D);
1020 }
1021 
1024  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1025  getPartialSpecializations();
1026  PS.clear();
1027  PS.reserve(PartialSpecs.size());
1028  for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1029  PS.push_back(P.getMostRecentDecl());
1030 }
1031 
1035  Decl *DCanon = D->getCanonicalDecl();
1036  for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1037  if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1038  return P.getMostRecentDecl();
1039  }
1040 
1041  return nullptr;
1042 }
1043 
1044 //===----------------------------------------------------------------------===//
1045 // VarTemplateSpecializationDecl Implementation
1046 //===----------------------------------------------------------------------===//
1047 
1049  Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1050  SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1052  : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1053  SpecializedTemplate->getIdentifier(), T, TInfo, S),
1054  SpecializedTemplate(SpecializedTemplate),
1055  TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1056  SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1057 
1059  ASTContext &C)
1060  : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1061  QualType(), nullptr, SC_None),
1062  SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1063 
1065  ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1066  SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1068  return new (Context, DC) VarTemplateSpecializationDecl(
1069  VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1070  SpecializedTemplate, T, TInfo, S, Args);
1071 }
1072 
1075  return new (C, ID)
1076  VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1077 }
1078 
1080  raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1081  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1082 
1083  const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1084  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1085  PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1086  printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1087  } else {
1088  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1089  printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1090  }
1091 }
1092 
1094  if (const auto *PartialSpec =
1095  SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1096  return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1097  return SpecializedTemplate.get<VarTemplateDecl *>();
1098 }
1099 
1101  const TemplateArgumentListInfo &ArgsInfo) {
1102  TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1103  TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1104  for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1105  TemplateArgsInfo.addArgument(Loc);
1106 }
1107 
1108 //===----------------------------------------------------------------------===//
1109 // VarTemplatePartialSpecializationDecl Implementation
1110 //===----------------------------------------------------------------------===//
1111 
1112 void VarTemplatePartialSpecializationDecl::anchor() {}
1113 
1114 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1115  ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1116  SourceLocation IdLoc, TemplateParameterList *Params,
1117  VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1119  const ASTTemplateArgumentListInfo *ArgInfos)
1120  : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1121  DC, StartLoc, IdLoc, SpecializedTemplate, T,
1122  TInfo, S, Args),
1123  TemplateParams(Params), ArgsAsWritten(ArgInfos),
1124  InstantiatedFromMember(nullptr, false) {
1125  // TODO: The template parameters should be in DC by now. Verify.
1126  // AdoptTemplateParameterList(Params, DC);
1127 }
1128 
1131  ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1132  SourceLocation IdLoc, TemplateParameterList *Params,
1133  VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1135  const TemplateArgumentListInfo &ArgInfos) {
1136  const ASTTemplateArgumentListInfo *ASTArgInfos
1137  = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1138 
1139  auto *Result =
1140  new (Context, DC) VarTemplatePartialSpecializationDecl(
1141  Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1142  S, Args, ASTArgInfos);
1143  Result->setSpecializationKind(TSK_ExplicitSpecialization);
1144  return Result;
1145 }
1146 
1149  unsigned ID) {
1150  return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1151 }
1152 
1153 static TemplateParameterList *
1155  // typename T
1156  auto *T = TemplateTypeParmDecl::Create(
1157  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1158  /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1159  T->setImplicit(true);
1160 
1161  // T ...Ints
1162  TypeSourceInfo *TI =
1163  C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1165  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166  /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1167  N->setImplicit(true);
1168 
1169  // <typename T, T ...Ints>
1170  NamedDecl *P[2] = {T, N};
1171  auto *TPL = TemplateParameterList::Create(
1172  C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1173 
1174  // template <typename T, ...Ints> class IntSeq
1175  auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1176  C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177  /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1178  TemplateTemplateParm->setImplicit(true);
1179 
1180  // typename T
1181  auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1182  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1183  /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1184  TemplateTypeParm->setImplicit(true);
1185 
1186  // T N
1188  QualType(TemplateTypeParm->getTypeForDecl(), 0));
1189  auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1190  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1191  /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192  NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1193  NonTypeTemplateParm};
1194 
1195  // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1197  Params, SourceLocation(), nullptr);
1198 }
1199 
1200 static TemplateParameterList *
1202  // std::size_t Index
1204  auto *Index = NonTypeTemplateParmDecl::Create(
1205  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1206  /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1207 
1208  // typename ...T
1209  auto *Ts = TemplateTypeParmDecl::Create(
1210  C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211  /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1212  Ts->setImplicit(true);
1213 
1214  // template <std::size_t Index, typename ...T>
1215  NamedDecl *Params[] = {Index, Ts};
1217  llvm::makeArrayRef(Params),
1218  SourceLocation(), nullptr);
1219 }
1220 
1222  const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1223  switch (BTK) {
1224  case BTK__make_integer_seq:
1225  return createMakeIntegerSeqParameterList(C, DC);
1227  return createTypePackElementParameterList(C, DC);
1228  }
1229 
1230  llvm_unreachable("unhandled BuiltinTemplateKind!");
1231 }
1232 
1233 void BuiltinTemplateDecl::anchor() {}
1234 
1235 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1236  DeclarationName Name,
1237  BuiltinTemplateKind BTK)
1238  : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1240  BTK(BTK) {}
Defines the clang::ASTContext interface.
void setImplicit(bool I=true)
Definition: DeclBase.h:548
Represents a function declaration or definition.
Definition: Decl.h:1739
A (possibly-)qualified type.
Definition: Type.h:638
virtual Decl * GetExternalDecl(uint32_t ID)
Resolve a declaration ID into a declaration, potentially building a new declaration.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
SourceRange getBraceRange() const
Definition: Decl.h:3154
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this functio...
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
C Language Family Type Representation.
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:126
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
Defines the C++ template declaration subclasses.
StringRef P
Declaration of a variable template.
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:133
A container of type source information.
Definition: Decl.h:86
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo)
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
SourceLocation getEndLoc() const
Get the end source location.
Definition: TypeLoc.cpp:227
void setRAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:572
Represents a variable declaration or definition.
Definition: Decl.h:812
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:380
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Declaration of a redeclarable template.
Definition: DeclTemplate.h:737
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
Represents a variable template specialization, which refers to a variable template with a given set o...
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:601
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:68
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:462
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
One of these records is kept for each identifier that is lexed.
Represents a class template specialization, which refers to a class template with a given set of temp...
unsigned getDepth() const
Retrieve the depth of the template parameter.
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
Defines the position of a template parameter within a template parameter list.
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void * allocateDefaultArgStorageChain(const ASTContext &C)
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
Stores the template parameter list and associated constraints for TemplateDecl objects that track ass...
Definition: DeclTemplate.h:370
Declaration of a function specialization at template class scope.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:508
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization. ...
A convenient class for passing around template argument information.
Definition: TemplateBase.h:552
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
static TemplateParameterList * createTypePackElementParameterList(const ASTContext &C, DeclContext *DC)
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:1857
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6076
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:728
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI)
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:977
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, ArrayRef< TemplateArgument > Args, void *&InsertPos)
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, unsigned ID)
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:103
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:688
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:876
This represents one expression.
Definition: Expr.h:106
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
void setAssociatedConstraints(Expr *AC)
Definition: DeclTemplate.h:487
SourceLocation End
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)
int Id
Definition: ASTDiff.cpp:191
Declaration of a template type parameter.
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
#define bool
Definition: stdbool.h:31
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Data that is common to all of the declarations of a given variable template.
SourceLocation Begin
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:264
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack...
Definition: DeclBase.cpp:201
Represents a C++ template name within the type system.
Definition: TemplateName.h:178
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy)
Print a template argument list, including the &#39;<&#39; and &#39;>&#39; enclosing the template arguments.
Defines the clang::TypeLoc interface and its subclasses.
StorageClass
Storage classes.
Definition: Specifiers.h:206
Declaration of an alias template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations()
Retrieve the set of partial specializations of this class template.
SourceLocation getEnd() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
Data that is common to all of the declarations of a given class template.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1395
The result type of a method or function.
void addDestruction(T *Ptr)
If T isn&#39;t trivially destructible, calls AddDeallocation to register it for destruction.
Definition: ASTContext.h:2719
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:703
static StringRef getIdentifier(const Token &Tok)
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2026
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl *> Params, SourceLocation RAngleLoc, Expr *RequiresClause)
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty alias template node.
#define false
Definition: stdbool.h:33
The "struct" keyword.
Definition: Type.h:5037
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
uint32_t * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:820
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
CommonBase * newCommon(ASTContext &C) const override
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
QualType InjectedClassNameType
The injected-class-name type for this class template.
bool isParameterPack() const
Returns whether this is a parameter pack.
Encodes a location in the source.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
This names the __make_integer_seq BuiltinTemplateDecl.
Definition: Builtins.h:245
CommonBase * newCommon(ASTContext &C) const override
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:974
static void AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template...
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:243
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList *> Params, FriendUnion Friend, SourceLocation FriendLoc)
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:164
This template specialization was formed from a template-id but has not yet been declared, defined, or instantiated.
Definition: Specifiers.h:149
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
static VarTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty variable template node.
static TemplateParameterList * createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC)
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
void setLAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:571
void addArgument(const TemplateArgumentLoc &Loc)
Definition: TemplateBase.h:592
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl, Expr *AssociatedConstraints=nullptr)
Create a class template node.
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:668
Represents a template argument.
Definition: TemplateBase.h:51
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
TagTypeKind
The kind of a tag type.
Definition: Type.h:5035
Dataflow Directional Tag Classes.
void getInjectedTemplateArgs(const TemplateParameterList *Params, SmallVectorImpl< TemplateArgument > &Args)
Get a template argument list with one argument per template parameter in a template parameter list...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1620
bool isValid() const
Return true if this is a valid SourceLocation object.
static ClassScopeFunctionSpecializationDecl * CreateDeserialized(ASTContext &Context, unsigned ID)
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:499
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1262
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty class template node.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:160
unsigned getIndex() const
Retrieve the index of the template parameter.
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
The name of a declaration.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID)
This names the __type_pack_element BuiltinTemplateDecl.
Definition: Builtins.h:248
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:146
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:580
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
Definition: ASTContext.h:1082
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:238
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:450
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
This template specialization was declared or defined by an explicit specialization (C++ [temp...
Definition: Specifiers.h:156
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args, const TemplateArgumentListInfo &ArgInfos)
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2268
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty function template node.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
A template argument list.
Definition: DeclTemplate.h:210
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:238
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
TemplateArgument * InjectedArgs
The set of "injected" template arguments used within this function template.
Definition: DeclTemplate.h:986
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl=nullptr) const
Retrieve the template type parameter type for a template parameter or parameter pack with the given d...
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
static const ASTTemplateArgumentListInfo * Create(ASTContext &C, const TemplateArgumentListInfo &List)
TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl *> Params, SourceLocation RAngleLoc, Expr *RequiresClause)
CommonBase * newCommon(ASTContext &C) const override
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
CommonBase * newCommon(ASTContext &C) const override
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
Declaration of a class template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:2912
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const
getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:90
SourceLocation getLAngleLoc() const
Definition: TemplateBase.h:568
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
A trivial tuple used to represent a source range.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
This represents a decl that may have a name.
Definition: Decl.h:248
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Declaration of a friend template.
SourceLocation getRAngleLoc() const
Definition: TemplateBase.h:569
VarTemplateDecl * getDefinition()
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:176
Defines enum values for all the target-independent builtin functions.
Declaration of a template function.
Definition: DeclTemplate.h:968
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
QualType getType() const
Return the type wrapped by this type source info.
Definition: Decl.h:97
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations()
Retrieve the set of partial specializations of this class template.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.