clang 17.0.0git
DeclTemplate.h
Go to the documentation of this file.
1//===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the C++ template declaration subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15#define LLVM_CLANG_AST_DECLTEMPLATE_H
16
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclBase.h"
21#include "clang/AST/DeclCXX.h"
25#include "clang/AST/Type.h"
26#include "clang/Basic/LLVM.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerIntPair.h"
32#include "llvm/ADT/PointerUnion.h"
33#include "llvm/ADT/iterator.h"
34#include "llvm/ADT/iterator_range.h"
35#include "llvm/Support/Casting.h"
36#include "llvm/Support/Compiler.h"
37#include "llvm/Support/TrailingObjects.h"
38#include <cassert>
39#include <cstddef>
40#include <cstdint>
41#include <iterator>
42#include <optional>
43#include <utility>
44
45namespace clang {
46
48class ClassTemplateDecl;
49class ClassTemplatePartialSpecializationDecl;
50class Expr;
51class FunctionTemplateDecl;
52class IdentifierInfo;
53class NonTypeTemplateParmDecl;
54class TemplateDecl;
55class TemplateTemplateParmDecl;
56class TemplateTypeParmDecl;
57class ConceptDecl;
58class UnresolvedSetImpl;
59class VarTemplateDecl;
60class VarTemplatePartialSpecializationDecl;
61
62/// Stores a template parameter of any kind.
64 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
66
68
69/// Stores a list of template parameters for a TemplateDecl and its
70/// derived classes.
72 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
73 Expr *> {
74 /// The location of the 'template' keyword.
75 SourceLocation TemplateLoc;
76
77 /// The locations of the '<' and '>' angle brackets.
78 SourceLocation LAngleLoc, RAngleLoc;
79
80 /// The number of template parameters in this template
81 /// parameter list.
82 unsigned NumParams : 29;
83
84 /// Whether this template parameter list contains an unexpanded parameter
85 /// pack.
86 unsigned ContainsUnexpandedParameterPack : 1;
87
88 /// Whether this template parameter list has a requires clause.
89 unsigned HasRequiresClause : 1;
90
91 /// Whether any of the template parameters has constrained-parameter
92 /// constraint-expression.
93 unsigned HasConstrainedParameters : 1;
94
95protected:
97 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
98 SourceLocation RAngleLoc, Expr *RequiresClause);
99
100 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
101 return NumParams;
102 }
103
104 size_t numTrailingObjects(OverloadToken<Expr *>) const {
105 return HasRequiresClause ? 1 : 0;
106 }
107
108public:
109 template <size_t N, bool HasRequiresClause>
112
114 SourceLocation TemplateLoc,
115 SourceLocation LAngleLoc,
117 SourceLocation RAngleLoc,
118 Expr *RequiresClause);
119
120 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
121
122 /// Iterates through the template parameters in this list.
123 using iterator = NamedDecl **;
124
125 /// Iterates through the template parameters in this list.
126 using const_iterator = NamedDecl * const *;
127
128 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
129 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
130 iterator end() { return begin() + NumParams; }
131 const_iterator end() const { return begin() + NumParams; }
132
133 unsigned size() const { return NumParams; }
134
137 return llvm::ArrayRef(begin(), size());
138 }
139
140 NamedDecl* getParam(unsigned Idx) {
141 assert(Idx < size() && "Template parameter index out-of-range");
142 return begin()[Idx];
143 }
144 const NamedDecl* getParam(unsigned Idx) const {
145 assert(Idx < size() && "Template parameter index out-of-range");
146 return begin()[Idx];
147 }
148
149 /// Returns the minimum number of arguments needed to form a
150 /// template specialization.
151 ///
152 /// This may be fewer than the number of template parameters, if some of
153 /// the parameters have default arguments or if there is a parameter pack.
154 unsigned getMinRequiredArguments() const;
155
156 /// Get the depth of this template parameter list in the set of
157 /// template parameter lists.
158 ///
159 /// The first template parameter list in a declaration will have depth 0,
160 /// the second template parameter list will have depth 1, etc.
161 unsigned getDepth() const;
162
163 /// Determine whether this template parameter list contains an
164 /// unexpanded parameter pack.
166
167 /// Determine whether this template parameter list contains a parameter pack.
168 bool hasParameterPack() const {
169 for (const NamedDecl *P : asArray())
170 if (P->isParameterPack())
171 return true;
172 return false;
173 }
174
175 /// The constraint-expression of the associated requires-clause.
177 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
178 }
179
180 /// The constraint-expression of the associated requires-clause.
181 const Expr *getRequiresClause() const {
182 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
183 }
184
185 /// \brief All associated constraints derived from this template parameter
186 /// list, including the requires clause and any constraints derived from
187 /// constrained-parameters.
188 ///
189 /// The constraints in the resulting list are to be treated as if in a
190 /// conjunction ("and").
192
194
195 SourceLocation getTemplateLoc() const { return TemplateLoc; }
196 SourceLocation getLAngleLoc() const { return LAngleLoc; }
197 SourceLocation getRAngleLoc() const { return RAngleLoc; }
198
199 SourceRange getSourceRange() const LLVM_READONLY {
200 return SourceRange(TemplateLoc, RAngleLoc);
201 }
202
203 void print(raw_ostream &Out, const ASTContext &Context,
204 bool OmitTemplateKW = false) const;
205 void print(raw_ostream &Out, const ASTContext &Context,
206 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
207
209 const TemplateParameterList *TPL,
210 unsigned Idx);
211};
212
213/// Stores a list of template parameters and the associated
214/// requires-clause (if any) for a TemplateDecl and its derived classes.
215/// Suitable for creating on the stack.
216template <size_t N, bool HasRequiresClause>
218 : public TemplateParameterList::FixedSizeStorageOwner {
219 typename TemplateParameterList::FixedSizeStorage<
220 NamedDecl *, Expr *>::with_counts<
221 N, HasRequiresClause ? 1u : 0u
222 >::type storage;
223
224public:
226 SourceLocation TemplateLoc,
227 SourceLocation LAngleLoc,
229 SourceLocation RAngleLoc,
230 Expr *RequiresClause)
231 : FixedSizeStorageOwner(
232 (assert(N == Params.size()),
233 assert(HasRequiresClause == (RequiresClause != nullptr)),
234 new (static_cast<void *>(&storage)) TemplateParameterList(C,
235 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
236};
237
238/// A template argument list.
240 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
241 /// The template argument list.
242 const TemplateArgument *Arguments;
243
244 /// The number of template arguments in this template
245 /// argument list.
246 unsigned NumArguments;
247
248 // Constructs an instance with an internal Argument list, containing
249 // a copy of the Args array. (Called by CreateCopy)
251
252public:
254
257
258 /// Type used to indicate that the template argument list itself is a
259 /// stack object. It does not own its template arguments.
261
262 /// Create a new template argument list that copies the given set of
263 /// template arguments.
266
267 /// Construct a new, temporary template argument list on the stack.
268 ///
269 /// The template argument list does not own the template arguments
270 /// provided.
272 : Arguments(Args.data()), NumArguments(Args.size()) {}
273
274 /// Produces a shallow copy of the given template argument list.
275 ///
276 /// This operation assumes that the input argument list outlives it.
277 /// This takes the list as a pointer to avoid looking like a copy
278 /// constructor, since this really isn't safe to use that way.
280 : Arguments(Other->data()), NumArguments(Other->size()) {}
281
282 /// Retrieve the template argument at a given index.
283 const TemplateArgument &get(unsigned Idx) const {
284 assert(Idx < NumArguments && "Invalid template argument index");
285 return data()[Idx];
286 }
287
288 /// Retrieve the template argument at a given index.
289 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
290
291 /// Produce this as an array ref.
293 return llvm::ArrayRef(data(), size());
294 }
295
296 /// Retrieve the number of template arguments in this
297 /// template argument list.
298 unsigned size() const { return NumArguments; }
299
300 /// Retrieve a pointer to the template argument list.
301 const TemplateArgument *data() const { return Arguments; }
302};
303
304void *allocateDefaultArgStorageChain(const ASTContext &C);
305
306/// Storage for a default argument. This is conceptually either empty, or an
307/// argument value, or a pointer to a previous declaration that had a default
308/// argument.
309///
310/// However, this is complicated by modules: while we require all the default
311/// arguments for a template to be equivalent, there may be more than one, and
312/// we need to track all the originating parameters to determine if the default
313/// argument is visible.
314template<typename ParmDecl, typename ArgType>
316 /// Storage for both the value *and* another parameter from which we inherit
317 /// the default argument. This is used when multiple default arguments for a
318 /// parameter are merged together from different modules.
319 struct Chain {
320 ParmDecl *PrevDeclWithDefaultArg;
321 ArgType Value;
322 };
323 static_assert(sizeof(Chain) == sizeof(void *) * 2,
324 "non-pointer argument type?");
325
326 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
327
328 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
329 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
330 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
331 Parm = Prev;
332 assert(!Parm->getDefaultArgStorage()
333 .ValueOrInherited.template is<ParmDecl *>() &&
334 "should only be one level of indirection");
335 return Parm;
336 }
337
338public:
339 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
340
341 /// Determine whether there is a default argument for this parameter.
342 bool isSet() const { return !ValueOrInherited.isNull(); }
343
344 /// Determine whether the default argument for this parameter was inherited
345 /// from a previous declaration of the same entity.
346 bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
347
348 /// Get the default argument's value. This does not consider whether the
349 /// default argument is visible.
350 ArgType get() const {
351 const DefaultArgStorage *Storage = this;
352 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
353 Storage = &Prev->getDefaultArgStorage();
354 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
355 return C->Value;
356 return Storage->ValueOrInherited.template get<ArgType>();
357 }
358
359 /// Get the parameter from which we inherit the default argument, if any.
360 /// This is the parameter on which the default argument was actually written.
361 const ParmDecl *getInheritedFrom() const {
362 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
363 return D;
364 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
365 return C->PrevDeclWithDefaultArg;
366 return nullptr;
367 }
368
369 /// Set the default argument.
370 void set(ArgType Arg) {
371 assert(!isSet() && "default argument already set");
372 ValueOrInherited = Arg;
373 }
374
375 /// Set that the default argument was inherited from another parameter.
376 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
377 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
378 if (!isSet())
379 ValueOrInherited = InheritedFrom;
380 else if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>()) {
381 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
382 ValueOrInherited =
383 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
384 } else if (auto *Inherited =
385 ValueOrInherited.template dyn_cast<Chain *>()) {
386 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
387 InheritedFrom));
388 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
389 } else
390 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
391 Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
392 }
393
394 /// Remove the default argument, even if it was inherited.
395 void clear() {
396 ValueOrInherited = ArgType();
397 }
398};
399
400//===----------------------------------------------------------------------===//
401// Kinds of Templates
402//===----------------------------------------------------------------------===//
403
404/// \brief The base class of all kinds of template declarations (e.g.,
405/// class, function, etc.).
406///
407/// The TemplateDecl class stores the list of template parameters and a
408/// reference to the templated scoped declaration: the underlying AST node.
409class TemplateDecl : public NamedDecl {
410 void anchor() override;
411
412protected:
413 // Construct a template decl with name, parameters, and templated element.
416
417 // Construct a template decl with the given name and parameters.
418 // Used when there is no templated element (e.g., for tt-params).
420 TemplateParameterList *Params)
421 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
422
423public:
424 friend class ASTDeclReader;
425 friend class ASTDeclWriter;
426
427 /// Get the list of template parameters
429 return TemplateParams;
430 }
431
432 /// \brief Get the total constraint-expression associated with this template,
433 /// including constraint-expressions derived from the requires-clause,
434 /// trailing requires-clause (for functions and methods) and constrained
435 /// template parameters.
437
438 bool hasAssociatedConstraints() const;
439
440 /// Get the underlying, templated declaration.
442
443 // Should a specialization behave like an alias for another type.
444 bool isTypeAlias() const;
445
446 // Implement isa/cast/dyncast/etc.
447 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
448
449 static bool classofKind(Kind K) {
450 return K >= firstTemplate && K <= lastTemplate;
451 }
452
453 SourceRange getSourceRange() const override LLVM_READONLY {
454 return SourceRange(getTemplateParameters()->getTemplateLoc(),
456 }
457
458protected:
461
462public:
464 TemplateParams = TParams;
465 }
466
467 /// Initialize the underlying templated declaration.
468 void init(NamedDecl *NewTemplatedDecl) {
469 if (TemplatedDecl)
470 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
471 else
472 TemplatedDecl = NewTemplatedDecl;
473 }
474};
475
476/// Provides information about a function template specialization,
477/// which is a FunctionDecl that has been explicitly specialization or
478/// instantiated from a function template.
480 : public llvm::FoldingSetNode,
481 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
482 MemberSpecializationInfo *> {
483 /// The function template specialization that this structure describes and a
484 /// flag indicating if the function is a member specialization.
485 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
486
487 /// The function template from which this function template
488 /// specialization was generated.
489 ///
490 /// The two bits contain the top 4 values of TemplateSpecializationKind.
491 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
492
493public:
494 /// The template arguments used to produce the function template
495 /// specialization from the function template.
497
498 /// The template arguments as written in the sources, if provided.
499 /// FIXME: Normally null; tail-allocate this.
501
502 /// The point at which this function template specialization was
503 /// first instantiated.
505
506private:
508 FunctionDecl *FD, FunctionTemplateDecl *Template,
509 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
510 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
512 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
513 TemplateArguments(TemplateArgs),
514 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
516 if (MSInfo)
517 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
518 }
519
520 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
521 return Function.getInt();
522 }
523
524public:
526
530 const TemplateArgumentList *TemplateArgs,
531 const TemplateArgumentListInfo *TemplateArgsAsWritten,
533
534 /// Retrieve the declaration of the function template specialization.
535 FunctionDecl *getFunction() const { return Function.getPointer(); }
536
537 /// Retrieve the template from which this function was specialized.
538 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
539
540 /// Determine what kind of template specialization this is.
542 return (TemplateSpecializationKind)(Template.getInt() + 1);
543 }
544
547 }
548
549 /// True if this declaration is an explicit specialization,
550 /// explicit instantiation declaration, or explicit instantiation
551 /// definition.
555 }
556
557 /// Set the template specialization kind.
559 assert(TSK != TSK_Undeclared &&
560 "Cannot encode TSK_Undeclared for a function template specialization");
561 Template.setInt(TSK - 1);
562 }
563
564 /// Retrieve the first point of instantiation of this function
565 /// template specialization.
566 ///
567 /// The point of instantiation may be an invalid source location if this
568 /// function has yet to be instantiated.
571 }
572
573 /// Set the (first) point of instantiation of this function template
574 /// specialization.
577 }
578
579 /// Get the specialization info if this function template specialization is
580 /// also a member specialization:
581 ///
582 /// \code
583 /// template<typename> struct A {
584 /// template<typename> void f();
585 /// template<> void f<int>(); // ClassScopeFunctionSpecializationDecl
586 /// };
587 /// \endcode
588 ///
589 /// Here, A<int>::f<int> is a function template specialization that is
590 /// an explicit specialization of A<int>::f, but it's also a member
591 /// specialization (an implicit instantiation in this case) of A::f<int>.
592 /// Further:
593 ///
594 /// \code
595 /// template<> template<> void A<int>::f<int>() {}
596 /// \endcode
597 ///
598 /// ... declares a function template specialization that is an explicit
599 /// specialization of A<int>::f, and is also an explicit member
600 /// specialization of A::f<int>.
601 ///
602 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
603 /// need not be the same as that returned by getTemplateSpecializationKind(),
604 /// and represents the relationship between the function and the class-scope
605 /// explicit specialization in the original templated class -- whereas our
606 /// TemplateSpecializationKind represents the relationship between the
607 /// function and the function template, and should always be
608 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
610 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
611 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
612 : nullptr;
613 }
614
615 void Profile(llvm::FoldingSetNodeID &ID) {
616 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
617 }
618
619 static void
620 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
621 const ASTContext &Context) {
622 ID.AddInteger(TemplateArgs.size());
623 for (const TemplateArgument &TemplateArg : TemplateArgs)
624 TemplateArg.Profile(ID, Context);
625 }
626};
627
628/// Provides information a specialization of a member of a class
629/// template, which may be a member function, static data member,
630/// member class or member enumeration.
632 // The member declaration from which this member was instantiated, and the
633 // manner in which the instantiation occurred (in the lower two bits).
634 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
635
636 // The point at which this member was first instantiated.
637 SourceLocation PointOfInstantiation;
638
639public:
640 explicit
643 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
644 assert(TSK != TSK_Undeclared &&
645 "Cannot encode undeclared template specializations for members");
646 }
647
648 /// Retrieve the member declaration from which this member was
649 /// instantiated.
650 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
651
652 /// Determine what kind of template specialization this is.
654 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
655 }
656
659 }
660
661 /// Set the template specialization kind.
663 assert(TSK != TSK_Undeclared &&
664 "Cannot encode undeclared template specializations for members");
665 MemberAndTSK.setInt(TSK - 1);
666 }
667
668 /// Retrieve the first point of instantiation of this member.
669 /// If the point of instantiation is an invalid location, then this member
670 /// has not yet been instantiated.
672 return PointOfInstantiation;
673 }
674
675 /// Set the first point of instantiation.
677 PointOfInstantiation = POI;
678 }
679};
680
681/// Provides information about a dependent function-template
682/// specialization declaration.
683///
684/// Since explicit function template specialization and instantiation
685/// declarations can only appear in namespace scope, and you can only
686/// specialize a member of a fully-specialized class, the only way to
687/// get one of these is in a friend declaration like the following:
688///
689/// \code
690/// template <class T> void foo(T);
691/// template <class T> class A {
692/// friend void foo<>(T);
693/// };
694/// \endcode
696 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
697 TemplateArgumentLoc,
698 FunctionTemplateDecl *> {
699 /// The number of potential template candidates.
700 unsigned NumTemplates;
701
702 /// The number of template arguments.
703 unsigned NumArgs;
704
705 /// The locations of the left and right angle brackets.
706 SourceRange AngleLocs;
707
708 size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
709 return NumArgs;
710 }
711 size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
712 return NumTemplates;
713 }
714
716 const UnresolvedSetImpl &Templates,
717 const TemplateArgumentListInfo &TemplateArgs);
718
719public:
721
723 Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
724 const TemplateArgumentListInfo &TemplateArgs);
725
726 /// Returns the number of function templates that this might
727 /// be a specialization of.
728 unsigned getNumTemplates() const { return NumTemplates; }
729
730 /// Returns the i'th template candidate.
732 assert(I < getNumTemplates() && "template index out of range");
733 return getTrailingObjects<FunctionTemplateDecl *>()[I];
734 }
735
736 /// Returns the explicit template arguments that were given.
738 return getTrailingObjects<TemplateArgumentLoc>();
739 }
740
741 /// Returns the number of explicit template arguments that were given.
742 unsigned getNumTemplateArgs() const { return NumArgs; }
743
746 }
747
748 /// Returns the nth template argument.
749 const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
750 assert(I < getNumTemplateArgs() && "template arg index out of range");
751 return getTemplateArgs()[I];
752 }
753
755 return AngleLocs.getBegin();
756 }
757
759 return AngleLocs.getEnd();
760 }
761};
762
763/// Declaration of a redeclarable template.
765 public Redeclarable<RedeclarableTemplateDecl>
766{
768
769 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
770 return getNextRedeclaration();
771 }
772
773 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
774 return getPreviousDecl();
775 }
776
777 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
778 return getMostRecentDecl();
779 }
780
781 void anchor() override;
782protected:
783 template <typename EntryType> struct SpecEntryTraits {
784 using DeclType = EntryType;
785
786 static DeclType *getDecl(EntryType *D) {
787 return D;
788 }
789
791 return D->getTemplateArgs().asArray();
792 }
793 };
794
795 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
796 typename DeclType = typename SETraits::DeclType>
798 : llvm::iterator_adaptor_base<
799 SpecIterator<EntryType, SETraits, DeclType>,
800 typename llvm::FoldingSetVector<EntryType>::iterator,
801 typename std::iterator_traits<typename llvm::FoldingSetVector<
802 EntryType>::iterator>::iterator_category,
803 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
804 SpecIterator() = default;
805 explicit SpecIterator(
806 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
807 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
808
809 DeclType *operator*() const {
810 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
811 }
812
813 DeclType *operator->() const { return **this; }
814 };
815
816 template <typename EntryType>
817 static SpecIterator<EntryType>
818 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
819 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
820 }
821
822 void loadLazySpecializationsImpl() const;
823
824 template <class EntryType, typename ...ProfileArguments>
826 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
827 void *&InsertPos, ProfileArguments &&...ProfileArgs);
828
829 template <class Derived, class EntryType>
830 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
831 EntryType *Entry, void *InsertPos);
832
833 struct CommonBase {
835
836 /// The template from which this was most
837 /// directly instantiated (or null).
838 ///
839 /// The boolean value indicates whether this template
840 /// was explicitly specialized.
841 llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
843
844 /// If non-null, points to an array of specializations (including
845 /// partial specializations) known only by their external declaration IDs.
846 ///
847 /// The first value in the array is the number of specializations/partial
848 /// specializations that follow.
849 uint32_t *LazySpecializations = nullptr;
850
851 /// The set of "injected" template arguments used within this
852 /// template.
853 ///
854 /// This pointer refers to the template arguments (there are as
855 /// many template arguments as template parameters) for the
856 /// template, and is allocated lazily, since most templates do not
857 /// require the use of this information.
859 };
860
861 /// Pointer to the common data shared by all declarations of this
862 /// template.
863 mutable CommonBase *Common = nullptr;
864
865 /// Retrieves the "common" pointer shared by all (re-)declarations of
866 /// the same template. Calling this routine may implicitly allocate memory
867 /// for the common pointer.
868 CommonBase *getCommonPtr() const;
869
870 virtual CommonBase *newCommon(ASTContext &C) const = 0;
871
872 // Construct a template decl with name, parameters, and templated element.
876 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
877
878public:
879 friend class ASTDeclReader;
880 friend class ASTDeclWriter;
881 friend class ASTReader;
882 template <class decl_type> friend class RedeclarableTemplate;
883
884 /// Retrieves the canonical declaration of this template.
886 return getFirstDecl();
887 }
889 return getFirstDecl();
890 }
891
892 /// Determines whether this template was a specialization of a
893 /// member template.
894 ///
895 /// In the following example, the function template \c X<int>::f and the
896 /// member template \c X<int>::Inner are member specializations.
897 ///
898 /// \code
899 /// template<typename T>
900 /// struct X {
901 /// template<typename U> void f(T, U);
902 /// template<typename U> struct Inner;
903 /// };
904 ///
905 /// template<> template<typename T>
906 /// void X<int>::f(int, T);
907 /// template<> template<typename T>
908 /// struct X<int>::Inner { /* ... */ };
909 /// \endcode
911 return getCommonPtr()->InstantiatedFromMember.getInt();
912 }
913
914 /// Note that this member template is a specialization.
916 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
917 "Only member templates can be member template specializations");
918 getCommonPtr()->InstantiatedFromMember.setInt(true);
919 }
920
921 /// Retrieve the member template from which this template was
922 /// instantiated, or nullptr if this template was not instantiated from a
923 /// member template.
924 ///
925 /// A template is instantiated from a member template when the member
926 /// template itself is part of a class template (or member thereof). For
927 /// example, given
928 ///
929 /// \code
930 /// template<typename T>
931 /// struct X {
932 /// template<typename U> void f(T, U);
933 /// };
934 ///
935 /// void test(X<int> x) {
936 /// x.f(1, 'a');
937 /// };
938 /// \endcode
939 ///
940 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
941 /// template
942 ///
943 /// \code
944 /// template<typename U> void X<int>::f(int, U);
945 /// \endcode
946 ///
947 /// which was itself created during the instantiation of \c X<int>. Calling
948 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
949 /// retrieve the FunctionTemplateDecl for the original template \c f within
950 /// the class template \c X<T>, i.e.,
951 ///
952 /// \code
953 /// template<typename T>
954 /// template<typename U>
955 /// void X<T>::f(T, U);
956 /// \endcode
958 return getCommonPtr()->InstantiatedFromMember.getPointer();
959 }
960
962 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
963 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
964 }
965
966 /// Retrieve the "injected" template arguments that correspond to the
967 /// template parameters of this template.
968 ///
969 /// Although the C++ standard has no notion of the "injected" template
970 /// arguments for a template, the notion is convenient when
971 /// we need to perform substitutions inside the definition of a template.
973
975 using redecl_iterator = redeclarable_base::redecl_iterator;
976
983
984 // Implement isa/cast/dyncast/etc.
985 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
986
987 static bool classofKind(Kind K) {
988 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
989 }
990};
991
992template <> struct RedeclarableTemplateDecl::
993SpecEntryTraits<FunctionTemplateSpecializationInfo> {
995
997 return I->getFunction();
998 }
999
1002 return I->TemplateArguments->asArray();
1003 }
1004};
1005
1006/// Declaration of a template function.
1008protected:
1009 friend class FunctionDecl;
1010
1011 /// Data that is common to all of the declarations of a given
1012 /// function template.
1014 /// The function template specializations for this function
1015 /// template, including explicit specializations and instantiations.
1016 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
1017
1018 Common() = default;
1019 };
1020
1023 NamedDecl *Decl)
1024 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
1025 Decl) {}
1026
1027 CommonBase *newCommon(ASTContext &C) const override;
1028
1030 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
1031 }
1032
1033 /// Retrieve the set of function template specializations of this
1034 /// function template.
1035 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
1036 getSpecializations() const;
1037
1038 /// Add a specialization of this function template.
1039 ///
1040 /// \param InsertPos Insert position in the FoldingSetVector, must have been
1041 /// retrieved by an earlier call to findSpecialization().
1043 void *InsertPos);
1044
1045public:
1046 friend class ASTDeclReader;
1047 friend class ASTDeclWriter;
1048
1049 /// Load any lazily-loaded specializations from the external source.
1050 void LoadLazySpecializations() const;
1051
1052 /// Get the underlying function declaration of the template.
1054 return static_cast<FunctionDecl *>(TemplatedDecl);
1055 }
1056
1057 /// Returns whether this template declaration defines the primary
1058 /// pattern.
1061 }
1062
1063 /// Return the specialization with the provided arguments if it exists,
1064 /// otherwise return the insertion point.
1066 void *&InsertPos);
1067
1069 return cast<FunctionTemplateDecl>(
1071 }
1073 return cast<FunctionTemplateDecl>(
1075 }
1076
1077 /// Retrieve the previous declaration of this function template, or
1078 /// nullptr if no such declaration exists.
1080 return cast_or_null<FunctionTemplateDecl>(
1081 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1082 }
1084 return cast_or_null<FunctionTemplateDecl>(
1085 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1086 }
1087
1089 return cast<FunctionTemplateDecl>(
1090 static_cast<RedeclarableTemplateDecl *>(this)
1091 ->getMostRecentDecl());
1092 }
1094 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1095 }
1096
1098 return cast_or_null<FunctionTemplateDecl>(
1100 }
1101
1103 using spec_range = llvm::iterator_range<spec_iterator>;
1104
1106 return spec_range(spec_begin(), spec_end());
1107 }
1108
1110 return makeSpecIterator(getSpecializations(), false);
1111 }
1112
1114 return makeSpecIterator(getSpecializations(), true);
1115 }
1116
1117 /// Return whether this function template is an abbreviated function template,
1118 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1119 bool isAbbreviated() const {
1120 // Since the invented template parameters generated from 'auto' parameters
1121 // are either appended to the end of the explicit template parameter list or
1122 // form a new template parameter list, we can simply observe the last
1123 // parameter to determine if such a thing happened.
1125 return TPL->getParam(TPL->size() - 1)->isImplicit();
1126 }
1127
1128 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1130
1131 /// Create a function template node.
1134 DeclarationName Name,
1135 TemplateParameterList *Params,
1136 NamedDecl *Decl);
1137
1138 /// Create an empty function template node.
1139 static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1140
1141 // Implement isa/cast/dyncast support
1142 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1143 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1144};
1145
1146//===----------------------------------------------------------------------===//
1147// Kinds of Template Parameters
1148//===----------------------------------------------------------------------===//
1149
1150/// Defines the position of a template parameter within a template
1151/// parameter list.
1152///
1153/// Because template parameter can be listed
1154/// sequentially for out-of-line template members, each template parameter is
1155/// given a Depth - the nesting of template parameter scopes - and a Position -
1156/// the occurrence within the parameter list.
1157/// This class is inheritedly privately by different kinds of template
1158/// parameters and is not part of the Decl hierarchy. Just a facility.
1160protected:
1161 enum { DepthWidth = 20, PositionWidth = 12 };
1162 unsigned Depth : DepthWidth;
1164
1165 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1166 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1167
1168 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1169 // The input may fill maximum values to show that it is invalid.
1170 // Add one here to convert it to zero.
1171 assert((D + 1) <= MaxDepth &&
1172 "The depth of template parmeter position is more than 2^20!");
1173 assert((P + 1) <= MaxPosition &&
1174 "The position of template parmeter position is more than 2^12!");
1175 }
1176
1177public:
1179
1180 /// Get the nesting depth of the template parameter.
1181 unsigned getDepth() const { return Depth; }
1182 void setDepth(unsigned D) {
1183 assert((D + 1) <= MaxDepth &&
1184 "The depth of template parmeter position is more than 2^20!");
1185 Depth = D;
1186 }
1187
1188 /// Get the position of the template parameter within its parameter list.
1189 unsigned getPosition() const { return Position; }
1190 void setPosition(unsigned P) {
1191 assert((P + 1) <= MaxPosition &&
1192 "The position of template parmeter position is more than 2^12!");
1193 Position = P;
1194 }
1195
1196 /// Get the index of the template parameter within its parameter list.
1197 unsigned getIndex() const { return Position; }
1198};
1199
1200/// Declaration of a template type parameter.
1201///
1202/// For example, "T" in
1203/// \code
1204/// template<typename T> class vector;
1205/// \endcode
1206class TemplateTypeParmDecl final : public TypeDecl,
1207 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1208 /// Sema creates these on the stack during auto type deduction.
1209 friend class Sema;
1210 friend TrailingObjects;
1211 friend class ASTDeclReader;
1212
1213 /// Whether this template type parameter was declaration with
1214 /// the 'typename' keyword.
1215 ///
1216 /// If false, it was declared with the 'class' keyword.
1217 bool Typename : 1;
1218
1219 /// Whether this template type parameter has a type-constraint construct.
1220 bool HasTypeConstraint : 1;
1221
1222 /// Whether the type constraint has been initialized. This can be false if the
1223 /// constraint was not initialized yet or if there was an error forming the
1224 /// type constraint.
1225 bool TypeConstraintInitialized : 1;
1226
1227 /// Whether this type template parameter is an "expanded"
1228 /// parameter pack, meaning that its type is a pack expansion and we
1229 /// already know the set of types that expansion expands to.
1230 bool ExpandedParameterPack : 1;
1231
1232 /// The number of type parameters in an expanded parameter pack.
1233 unsigned NumExpanded = 0;
1234
1235 /// The default template argument, if any.
1236 using DefArgStorage =
1238 DefArgStorage DefaultArgument;
1239
1241 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1242 bool HasTypeConstraint,
1243 std::optional<unsigned> NumExpanded)
1244 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1245 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1246 ExpandedParameterPack(NumExpanded),
1247 NumExpanded(NumExpanded.value_or(0)) {}
1248
1249public:
1250 static TemplateTypeParmDecl *
1251 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1252 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1253 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1254 std::optional<unsigned> NumExpanded = std::nullopt);
1256 unsigned ID);
1258 unsigned ID,
1259 bool HasTypeConstraint);
1260
1261 /// Whether this template type parameter was declared with
1262 /// the 'typename' keyword.
1263 ///
1264 /// If not, it was either declared with the 'class' keyword or with a
1265 /// type-constraint (see hasTypeConstraint()).
1267 return Typename && !HasTypeConstraint;
1268 }
1269
1270 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1271
1272 /// Determine whether this template parameter has a default
1273 /// argument.
1274 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1275
1276 /// Retrieve the default argument, if any.
1278 return DefaultArgument.get()->getType();
1279 }
1280
1281 /// Retrieves the default argument's source information, if any.
1283 return DefaultArgument.get();
1284 }
1285
1286 /// Retrieves the location of the default argument declaration.
1288
1289 /// Determines whether the default argument was inherited
1290 /// from a previous declaration of this template.
1292 return DefaultArgument.isInherited();
1293 }
1294
1295 /// Set the default argument for this template parameter.
1297 DefaultArgument.set(DefArg);
1298 }
1299
1300 /// Set that this default argument was inherited from another
1301 /// parameter.
1303 TemplateTypeParmDecl *Prev) {
1304 DefaultArgument.setInherited(C, Prev);
1305 }
1306
1307 /// Removes the default argument of this template parameter.
1309 DefaultArgument.clear();
1310 }
1311
1312 /// Set whether this template type parameter was declared with
1313 /// the 'typename' or 'class' keyword.
1314 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1315
1316 /// Retrieve the depth of the template parameter.
1317 unsigned getDepth() const;
1318
1319 /// Retrieve the index of the template parameter.
1320 unsigned getIndex() const;
1321
1322 /// Returns whether this is a parameter pack.
1323 bool isParameterPack() const;
1324
1325 /// Whether this parameter pack is a pack expansion.
1326 ///
1327 /// A template type template parameter pack can be a pack expansion if its
1328 /// type-constraint contains an unexpanded parameter pack.
1329 bool isPackExpansion() const {
1330 if (!isParameterPack())
1331 return false;
1332 if (const TypeConstraint *TC = getTypeConstraint())
1333 if (TC->hasExplicitTemplateArgs())
1334 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1335 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1336 return true;
1337 return false;
1338 }
1339
1340 /// Whether this parameter is a template type parameter pack that has a known
1341 /// list of different type-constraints at different positions.
1342 ///
1343 /// A parameter pack is an expanded parameter pack when the original
1344 /// parameter pack's type-constraint was itself a pack expansion, and that
1345 /// expansion has already been expanded. For example, given:
1346 ///
1347 /// \code
1348 /// template<typename ...Types>
1349 /// struct X {
1350 /// template<convertible_to<Types> ...Convertibles>
1351 /// struct Y { /* ... */ };
1352 /// };
1353 /// \endcode
1354 ///
1355 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1356 /// its type-constraint. When \c Types is supplied with template arguments by
1357 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1358 /// expanded parameter pack. For example, instantiating
1359 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1360 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1361 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1362
1363 /// Retrieves the number of parameters in an expanded parameter pack.
1364 unsigned getNumExpansionParameters() const {
1365 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1366 return NumExpanded;
1367 }
1368
1369 /// Returns the type constraint associated with this template parameter (if
1370 /// any).
1372 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1373 nullptr;
1374 }
1375
1377 DeclarationNameInfo NameInfo, NamedDecl *FoundDecl,
1378 ConceptDecl *CD,
1379 const ASTTemplateArgumentListInfo *ArgsAsWritten,
1380 Expr *ImmediatelyDeclaredConstraint);
1381
1382 /// Determine whether this template parameter has a type-constraint.
1383 bool hasTypeConstraint() const {
1384 return HasTypeConstraint;
1385 }
1386
1387 /// \brief Get the associated-constraints of this template parameter.
1388 /// This will either be the immediately-introduced constraint or empty.
1389 ///
1390 /// Use this instead of getTypeConstraint for concepts APIs that
1391 /// accept an ArrayRef of constraint expressions.
1393 if (HasTypeConstraint)
1394 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1395 }
1396
1397 SourceRange getSourceRange() const override LLVM_READONLY;
1398
1399 // Implement isa/cast/dyncast/etc.
1400 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1401 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1402};
1403
1404/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1405/// e.g., "Size" in
1406/// @code
1407/// template<int Size> class array { };
1408/// @endcode
1410 : public DeclaratorDecl,
1411 protected TemplateParmPosition,
1412 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1413 std::pair<QualType, TypeSourceInfo *>,
1414 Expr *> {
1415 friend class ASTDeclReader;
1416 friend TrailingObjects;
1417
1418 /// The default template argument, if any, and whether or not
1419 /// it was inherited.
1421 DefArgStorage DefaultArgument;
1422
1423 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1424 // down here to save memory.
1425
1426 /// Whether this non-type template parameter is a parameter pack.
1427 bool ParameterPack;
1428
1429 /// Whether this non-type template parameter is an "expanded"
1430 /// parameter pack, meaning that its type is a pack expansion and we
1431 /// already know the set of types that expansion expands to.
1432 bool ExpandedParameterPack = false;
1433
1434 /// The number of types in an expanded parameter pack.
1435 unsigned NumExpandedTypes = 0;
1436
1437 size_t numTrailingObjects(
1438 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1439 return NumExpandedTypes;
1440 }
1441
1443 SourceLocation IdLoc, unsigned D, unsigned P,
1445 bool ParameterPack, TypeSourceInfo *TInfo)
1446 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1447 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1448
1449 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1450 SourceLocation IdLoc, unsigned D, unsigned P,
1451 IdentifierInfo *Id, QualType T,
1452 TypeSourceInfo *TInfo,
1453 ArrayRef<QualType> ExpandedTypes,
1454 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1455
1456public:
1457 static NonTypeTemplateParmDecl *
1458 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1459 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1460 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1461
1462 static NonTypeTemplateParmDecl *
1463 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1464 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1465 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1466 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1467
1468 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1469 unsigned ID,
1470 bool HasTypeConstraint);
1471 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1472 unsigned ID,
1473 unsigned NumExpandedTypes,
1474 bool HasTypeConstraint);
1475
1481
1482 SourceRange getSourceRange() const override LLVM_READONLY;
1483
1484 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1485
1486 /// Determine whether this template parameter has a default
1487 /// argument.
1488 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1489
1490 /// Retrieve the default argument, if any.
1491 Expr *getDefaultArgument() const { return DefaultArgument.get(); }
1492
1493 /// Retrieve the location of the default argument, if any.
1495
1496 /// Determines whether the default argument was inherited
1497 /// from a previous declaration of this template.
1499 return DefaultArgument.isInherited();
1500 }
1501
1502 /// Set the default argument for this template parameter, and
1503 /// whether that default argument was inherited from another
1504 /// declaration.
1505 void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
1508 DefaultArgument.setInherited(C, Parm);
1509 }
1510
1511 /// Removes the default argument of this template parameter.
1512 void removeDefaultArgument() { DefaultArgument.clear(); }
1513
1514 /// Whether this parameter is a non-type template parameter pack.
1515 ///
1516 /// If the parameter is a parameter pack, the type may be a
1517 /// \c PackExpansionType. In the following example, the \c Dims parameter
1518 /// is a parameter pack (whose type is 'unsigned').
1519 ///
1520 /// \code
1521 /// template<typename T, unsigned ...Dims> struct multi_array;
1522 /// \endcode
1523 bool isParameterPack() const { return ParameterPack; }
1524
1525 /// Whether this parameter pack is a pack expansion.
1526 ///
1527 /// A non-type template parameter pack is a pack expansion if its type
1528 /// contains an unexpanded parameter pack. In this case, we will have
1529 /// built a PackExpansionType wrapping the type.
1530 bool isPackExpansion() const {
1531 return ParameterPack && getType()->getAs<PackExpansionType>();
1532 }
1533
1534 /// Whether this parameter is a non-type template parameter pack
1535 /// that has a known list of different types at different positions.
1536 ///
1537 /// A parameter pack is an expanded parameter pack when the original
1538 /// parameter pack's type was itself a pack expansion, and that expansion
1539 /// has already been expanded. For example, given:
1540 ///
1541 /// \code
1542 /// template<typename ...Types>
1543 /// struct X {
1544 /// template<Types ...Values>
1545 /// struct Y { /* ... */ };
1546 /// };
1547 /// \endcode
1548 ///
1549 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1550 /// which expands \c Types. When \c Types is supplied with template arguments
1551 /// by instantiating \c X, the instantiation of \c Values becomes an
1552 /// expanded parameter pack. For example, instantiating
1553 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1554 /// pack with expansion types \c int and \c unsigned int.
1555 ///
1556 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1557 /// return the expansion types.
1558 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1559
1560 /// Retrieves the number of expansion types in an expanded parameter
1561 /// pack.
1562 unsigned getNumExpansionTypes() const {
1563 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1564 return NumExpandedTypes;
1565 }
1566
1567 /// Retrieve a particular expansion type within an expanded parameter
1568 /// pack.
1569 QualType getExpansionType(unsigned I) const {
1570 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1571 auto TypesAndInfos =
1572 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1573 return TypesAndInfos[I].first;
1574 }
1575
1576 /// Retrieve a particular expansion type source info within an
1577 /// expanded parameter pack.
1579 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1580 auto TypesAndInfos =
1581 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1582 return TypesAndInfos[I].second;
1583 }
1584
1585 /// Return the constraint introduced by the placeholder type of this non-type
1586 /// template parameter (if any).
1588 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1589 nullptr;
1590 }
1591
1593 *getTrailingObjects<Expr *>() = E;
1594 }
1595
1596 /// Determine whether this non-type template parameter's type has a
1597 /// placeholder with a type-constraint.
1599 auto *AT = getType()->getContainedAutoType();
1600 return AT && AT->isConstrained();
1601 }
1602
1603 /// \brief Get the associated-constraints of this template parameter.
1604 /// This will either be a vector of size 1 containing the immediately-declared
1605 /// constraint introduced by the placeholder type, or an empty vector.
1606 ///
1607 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1608 /// concepts APIs that accept an ArrayRef of constraint expressions.
1611 AC.push_back(E);
1612 }
1613
1614 // Implement isa/cast/dyncast/etc.
1615 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1616 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1617};
1618
1619/// TemplateTemplateParmDecl - Declares a template template parameter,
1620/// e.g., "T" in
1621/// @code
1622/// template <template <typename> class T> class container { };
1623/// @endcode
1624/// A template template parameter is a TemplateDecl because it defines the
1625/// name of a template and the template parameters allowable for substitution.
1627 : public TemplateDecl,
1628 protected TemplateParmPosition,
1629 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1630 TemplateParameterList *> {
1631 /// The default template argument, if any.
1632 using DefArgStorage =
1634 DefArgStorage DefaultArgument;
1635
1636 /// Whether this parameter is a parameter pack.
1637 bool ParameterPack;
1638
1639 /// Whether this template template parameter is an "expanded"
1640 /// parameter pack, meaning that it is a pack expansion and we
1641 /// already know the set of template parameters that expansion expands to.
1642 bool ExpandedParameterPack = false;
1643
1644 /// The number of parameters in an expanded parameter pack.
1645 unsigned NumExpandedParams = 0;
1646
1648 unsigned D, unsigned P, bool ParameterPack,
1650 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1651 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1652
1654 unsigned D, unsigned P,
1657
1658 void anchor() override;
1659
1660public:
1661 friend class ASTDeclReader;
1662 friend class ASTDeclWriter;
1664
1666 SourceLocation L, unsigned D,
1667 unsigned P, bool ParameterPack,
1669 TemplateParameterList *Params);
1671 SourceLocation L, unsigned D,
1672 unsigned P,
1674 TemplateParameterList *Params,
1676
1678 unsigned ID);
1680 unsigned ID,
1681 unsigned NumExpansions);
1682
1688
1689 /// Whether this template template parameter is a template
1690 /// parameter pack.
1691 ///
1692 /// \code
1693 /// template<template <class T> ...MetaFunctions> struct Apply;
1694 /// \endcode
1695 bool isParameterPack() const { return ParameterPack; }
1696
1697 /// Whether this parameter pack is a pack expansion.
1698 ///
1699 /// A template template parameter pack is a pack expansion if its template
1700 /// parameter list contains an unexpanded parameter pack.
1701 bool isPackExpansion() const {
1702 return ParameterPack &&
1704 }
1705
1706 /// Whether this parameter is a template template parameter pack that
1707 /// has a known list of different template parameter lists at different
1708 /// positions.
1709 ///
1710 /// A parameter pack is an expanded parameter pack when the original parameter
1711 /// pack's template parameter list was itself a pack expansion, and that
1712 /// expansion has already been expanded. For exampe, given:
1713 ///
1714 /// \code
1715 /// template<typename...Types> struct Outer {
1716 /// template<template<Types> class...Templates> struct Inner;
1717 /// };
1718 /// \endcode
1719 ///
1720 /// The parameter pack \c Templates is a pack expansion, which expands the
1721 /// pack \c Types. When \c Types is supplied with template arguments by
1722 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1723 /// parameter pack.
1724 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1725
1726 /// Retrieves the number of expansion template parameters in
1727 /// an expanded parameter pack.
1729 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1730 return NumExpandedParams;
1731 }
1732
1733 /// Retrieve a particular expansion type within an expanded parameter
1734 /// pack.
1736 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1737 return getTrailingObjects<TemplateParameterList *>()[I];
1738 }
1739
1740 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1741
1742 /// Determine whether this template parameter has a default
1743 /// argument.
1744 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1745
1746 /// Retrieve the default argument, if any.
1748 static const TemplateArgumentLoc NoneLoc;
1749 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1750 }
1751
1752 /// Retrieve the location of the default argument, if any.
1754
1755 /// Determines whether the default argument was inherited
1756 /// from a previous declaration of this template.
1758 return DefaultArgument.isInherited();
1759 }
1760
1761 /// Set the default argument for this template parameter, and
1762 /// whether that default argument was inherited from another
1763 /// declaration.
1764 void setDefaultArgument(const ASTContext &C,
1765 const TemplateArgumentLoc &DefArg);
1768 DefaultArgument.setInherited(C, Prev);
1769 }
1770
1771 /// Removes the default argument of this template parameter.
1772 void removeDefaultArgument() { DefaultArgument.clear(); }
1773
1774 SourceRange getSourceRange() const override LLVM_READONLY {
1778 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1779 }
1780
1781 // Implement isa/cast/dyncast/etc.
1782 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1783 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1784};
1785
1786/// Represents the builtin template declaration which is used to
1787/// implement __make_integer_seq and other builtin templates. It serves
1788/// no real purpose beyond existing as a place to hold template parameters.
1791
1794
1795 void anchor() override;
1796
1797public:
1798 // Implement isa/cast/dyncast support
1799 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1800 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1801
1803 DeclarationName Name,
1804 BuiltinTemplateKind BTK) {
1805 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1806 }
1807
1808 SourceRange getSourceRange() const override LLVM_READONLY {
1809 return {};
1810 }
1811
1813};
1814
1815/// Represents a class template specialization, which refers to
1816/// a class template with a given set of template arguments.
1817///
1818/// Class template specializations represent both explicit
1819/// specialization of class templates, as in the example below, and
1820/// implicit instantiations of class templates.
1821///
1822/// \code
1823/// template<typename T> class array;
1824///
1825/// template<>
1826/// class array<bool> { }; // class template specialization array<bool>
1827/// \endcode
1829 : public CXXRecordDecl, public llvm::FoldingSetNode {
1830 /// Structure that stores information about a class template
1831 /// specialization that was instantiated from a class template partial
1832 /// specialization.
1833 struct SpecializedPartialSpecialization {
1834 /// The class template partial specialization from which this
1835 /// class template specialization was instantiated.
1836 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1837
1838 /// The template argument list deduced for the class template
1839 /// partial specialization itself.
1840 const TemplateArgumentList *TemplateArgs;
1841 };
1842
1843 /// The template that this specialization specializes
1844 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1845 SpecializedTemplate;
1846
1847 /// Further info for explicit template specialization/instantiation.
1848 struct ExplicitSpecializationInfo {
1849 /// The type-as-written.
1850 TypeSourceInfo *TypeAsWritten = nullptr;
1851
1852 /// The location of the extern keyword.
1853 SourceLocation ExternLoc;
1854
1855 /// The location of the template keyword.
1856 SourceLocation TemplateKeywordLoc;
1857
1858 ExplicitSpecializationInfo() = default;
1859 };
1860
1861 /// Further info for explicit template specialization/instantiation.
1862 /// Does not apply to implicit specializations.
1863 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
1864
1865 /// The template arguments used to describe this specialization.
1866 const TemplateArgumentList *TemplateArgs;
1867
1868 /// The point where this template was instantiated (if any)
1869 SourceLocation PointOfInstantiation;
1870
1871 /// The kind of specialization this declaration refers to.
1872 /// Really a value of type TemplateSpecializationKind.
1873 unsigned SpecializationKind : 3;
1874
1875protected:
1877 DeclContext *DC, SourceLocation StartLoc,
1878 SourceLocation IdLoc,
1879 ClassTemplateDecl *SpecializedTemplate,
1882
1884
1885public:
1886 friend class ASTDeclReader;
1887 friend class ASTDeclWriter;
1888
1890 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1891 SourceLocation StartLoc, SourceLocation IdLoc,
1892 ClassTemplateDecl *SpecializedTemplate,
1896 CreateDeserialized(ASTContext &C, unsigned ID);
1897
1898 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1899 bool Qualified) const override;
1900
1901 // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1902 // different "most recent" declaration from this function for the same
1903 // declaration, because we don't override getMostRecentDeclImpl(). But
1904 // it's not clear that we should override that, because the most recent
1905 // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1907 return cast<ClassTemplateSpecializationDecl>(
1909 }
1910
1911 /// Retrieve the template that this specialization specializes.
1913
1914 /// Retrieve the template arguments of the class template
1915 /// specialization.
1917 return *TemplateArgs;
1918 }
1919
1921 TemplateArgs = Args;
1922 }
1923
1924 /// Determine the kind of specialization that this
1925 /// declaration represents.
1927 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1928 }
1929
1932 }
1933
1934 /// Is this an explicit specialization at class scope (within the class that
1935 /// owns the primary template)? For example:
1936 ///
1937 /// \code
1938 /// template<typename T> struct Outer {
1939 /// template<typename U> struct Inner;
1940 /// template<> struct Inner; // class-scope explicit specialization
1941 /// };
1942 /// \endcode
1944 return isExplicitSpecialization() &&
1945 isa<CXXRecordDecl>(getLexicalDeclContext());
1946 }
1947
1948 /// True if this declaration is an explicit specialization,
1949 /// explicit instantiation declaration, or explicit instantiation
1950 /// definition.
1954 }
1955
1957 SpecializedTemplate = Specialized;
1958 }
1959
1961 SpecializationKind = TSK;
1962 }
1963
1964 /// Get the point of instantiation (if any), or null if none.
1966 return PointOfInstantiation;
1967 }
1968
1970 assert(Loc.isValid() && "point of instantiation must be valid!");
1971 PointOfInstantiation = Loc;
1972 }
1973
1974 /// If this class template specialization is an instantiation of
1975 /// a template (rather than an explicit specialization), return the
1976 /// class template or class template partial specialization from which it
1977 /// was instantiated.
1978 llvm::PointerUnion<ClassTemplateDecl *,
1982 return llvm::PointerUnion<ClassTemplateDecl *,
1984
1986 }
1987
1988 /// Retrieve the class template or class template partial
1989 /// specialization which was specialized by this.
1990 llvm::PointerUnion<ClassTemplateDecl *,
1993 if (const auto *PartialSpec =
1994 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1995 return PartialSpec->PartialSpecialization;
1996
1997 return SpecializedTemplate.get<ClassTemplateDecl*>();
1998 }
1999
2000 /// Retrieve the set of template arguments that should be used
2001 /// to instantiate members of the class template or class template partial
2002 /// specialization from which this class template specialization was
2003 /// instantiated.
2004 ///
2005 /// \returns For a class template specialization instantiated from the primary
2006 /// template, this function will return the same template arguments as
2007 /// getTemplateArgs(). For a class template specialization instantiated from
2008 /// a class template partial specialization, this function will return the
2009 /// deduced template arguments for the class template partial specialization
2010 /// itself.
2012 if (const auto *PartialSpec =
2013 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2014 return *PartialSpec->TemplateArgs;
2015
2016 return getTemplateArgs();
2017 }
2018
2019 /// Note that this class template specialization is actually an
2020 /// instantiation of the given class template partial specialization whose
2021 /// template arguments have been deduced.
2023 const TemplateArgumentList *TemplateArgs) {
2024 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
2025 "Already set to a class template partial specialization!");
2026 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2027 PS->PartialSpecialization = PartialSpec;
2028 PS->TemplateArgs = TemplateArgs;
2029 SpecializedTemplate = PS;
2030 }
2031
2032 /// Note that this class template specialization is an instantiation
2033 /// of the given class template.
2035 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
2036 "Previously set to a class template partial specialization!");
2037 SpecializedTemplate = TemplDecl;
2038 }
2039
2040 /// Sets the type of this specialization as it was written by
2041 /// the user. This will be a class template specialization type.
2043 if (!ExplicitInfo)
2044 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2045 ExplicitInfo->TypeAsWritten = T;
2046 }
2047
2048 /// Gets the type of this specialization as it was written by
2049 /// the user, if it was so written.
2051 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2052 }
2053
2054 /// Gets the location of the extern keyword, if present.
2056 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2057 }
2058
2059 /// Sets the location of the extern keyword.
2061 if (!ExplicitInfo)
2062 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2063 ExplicitInfo->ExternLoc = Loc;
2064 }
2065
2066 /// Sets the location of the template keyword.
2068 if (!ExplicitInfo)
2069 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2070 ExplicitInfo->TemplateKeywordLoc = Loc;
2071 }
2072
2073 /// Gets the location of the template keyword, if present.
2075 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2076 }
2077
2078 SourceRange getSourceRange() const override LLVM_READONLY;
2079
2080 void Profile(llvm::FoldingSetNodeID &ID) const {
2081 Profile(ID, TemplateArgs->asArray(), getASTContext());
2082 }
2083
2084 static void
2085 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2086 const ASTContext &Context) {
2087 ID.AddInteger(TemplateArgs.size());
2088 for (const TemplateArgument &TemplateArg : TemplateArgs)
2089 TemplateArg.Profile(ID, Context);
2090 }
2091
2092 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2093
2094 static bool classofKind(Kind K) {
2095 return K >= firstClassTemplateSpecialization &&
2096 K <= lastClassTemplateSpecialization;
2097 }
2098};
2099
2102 /// The list of template parameters
2103 TemplateParameterList* TemplateParams = nullptr;
2104
2105 /// The source info for the template arguments as written.
2106 /// FIXME: redundant with TypeAsWritten?
2107 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2108
2109 /// The class template partial specialization from which this
2110 /// class template partial specialization was instantiated.
2111 ///
2112 /// The boolean value will be true to indicate that this class template
2113 /// partial specialization was specialized at this level.
2114 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2115 InstantiatedFromMember;
2116
2118 DeclContext *DC,
2119 SourceLocation StartLoc,
2120 SourceLocation IdLoc,
2121 TemplateParameterList *Params,
2122 ClassTemplateDecl *SpecializedTemplate,
2124 const ASTTemplateArgumentListInfo *ArgsAsWritten,
2126
2128 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2129 InstantiatedFromMember(nullptr, false) {}
2130
2131 void anchor() override;
2132
2133public:
2134 friend class ASTDeclReader;
2135 friend class ASTDeclWriter;
2136
2138 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2139 SourceLocation StartLoc, SourceLocation IdLoc,
2140 TemplateParameterList *Params,
2141 ClassTemplateDecl *SpecializedTemplate,
2143 const TemplateArgumentListInfo &ArgInfos,
2144 QualType CanonInjectedType,
2146
2148 CreateDeserialized(ASTContext &C, unsigned ID);
2149
2151 return cast<ClassTemplatePartialSpecializationDecl>(
2152 static_cast<ClassTemplateSpecializationDecl *>(
2153 this)->getMostRecentDecl());
2154 }
2155
2156 /// Get the list of template parameters
2158 return TemplateParams;
2159 }
2160
2161 /// \brief All associated constraints of this partial specialization,
2162 /// including the requires clause and any constraints derived from
2163 /// constrained-parameters.
2164 ///
2165 /// The constraints in the resulting list are to be treated as if in a
2166 /// conjunction ("and").
2168 TemplateParams->getAssociatedConstraints(AC);
2169 }
2170
2172 return TemplateParams->hasAssociatedConstraints();
2173 }
2174
2175 /// Get the template arguments as written.
2177 return ArgsAsWritten;
2178 }
2179
2180 /// Retrieve the member class template partial specialization from
2181 /// which this particular class template partial specialization was
2182 /// instantiated.
2183 ///
2184 /// \code
2185 /// template<typename T>
2186 /// struct Outer {
2187 /// template<typename U> struct Inner;
2188 /// template<typename U> struct Inner<U*> { }; // #1
2189 /// };
2190 ///
2191 /// Outer<float>::Inner<int*> ii;
2192 /// \endcode
2193 ///
2194 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2195 /// end up instantiating the partial specialization
2196 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2197 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2198 /// \c Outer<float>::Inner<U*>, this function would return
2199 /// \c Outer<T>::Inner<U*>.
2201 const auto *First =
2202 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2203 return First->InstantiatedFromMember.getPointer();
2204 }
2208 }
2209
2212 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2213 First->InstantiatedFromMember.setPointer(PartialSpec);
2214 }
2215
2216 /// Determines whether this class template partial specialization
2217 /// template was a specialization of a member partial specialization.
2218 ///
2219 /// In the following example, the member template partial specialization
2220 /// \c X<int>::Inner<T*> is a member specialization.
2221 ///
2222 /// \code
2223 /// template<typename T>
2224 /// struct X {
2225 /// template<typename U> struct Inner;
2226 /// template<typename U> struct Inner<U*>;
2227 /// };
2228 ///
2229 /// template<> template<typename T>
2230 /// struct X<int>::Inner<T*> { /* ... */ };
2231 /// \endcode
2233 const auto *First =
2234 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2235 return First->InstantiatedFromMember.getInt();
2236 }
2237
2238 /// Note that this member template is a specialization.
2240 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2241 assert(First->InstantiatedFromMember.getPointer() &&
2242 "Only member templates can be member template specializations");
2243 return First->InstantiatedFromMember.setInt(true);
2244 }
2245
2246 /// Retrieves the injected specialization type for this partial
2247 /// specialization. This is not the same as the type-decl-type for
2248 /// this partial specialization, which is an InjectedClassNameType.
2250 assert(getTypeForDecl() && "partial specialization has no type set!");
2251 return cast<InjectedClassNameType>(getTypeForDecl())
2252 ->getInjectedSpecializationType();
2253 }
2254
2255 void Profile(llvm::FoldingSetNodeID &ID) const {
2257 getASTContext());
2258 }
2259
2260 static void
2261 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2262 TemplateParameterList *TPL, const ASTContext &Context);
2263
2264 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2265
2266 static bool classofKind(Kind K) {
2267 return K == ClassTemplatePartialSpecialization;
2268 }
2269};
2270
2271/// Declaration of a class template.
2273protected:
2274 /// Data that is common to all of the declarations of a given
2275 /// class template.
2277 /// The class template specializations for this class
2278 /// template, including explicit specializations and instantiations.
2279 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2280
2281 /// The class template partial specializations for this class
2282 /// template.
2283 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2285
2286 /// The injected-class-name type for this class template.
2288
2289 Common() = default;
2290 };
2291
2292 /// Retrieve the set of specializations of this class template.
2293 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2294 getSpecializations() const;
2295
2296 /// Retrieve the set of partial specializations of this class
2297 /// template.
2298 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2300
2303 NamedDecl *Decl)
2304 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2305
2306 CommonBase *newCommon(ASTContext &C) const override;
2307
2309 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2310 }
2311
2314 }
2315
2316public:
2317
2318 friend class ASTDeclReader;
2319 friend class ASTDeclWriter;
2321
2322 /// Load any lazily-loaded specializations from the external source.
2323 void LoadLazySpecializations() const;
2324
2325 /// Get the underlying class declarations of the template.
2327 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2328 }
2329
2330 /// Returns whether this template declaration defines the primary
2331 /// class pattern.
2334 }
2335
2336 /// \brief Create a class template node.
2339 DeclarationName Name,
2340 TemplateParameterList *Params,
2341 NamedDecl *Decl);
2342
2343 /// Create an empty class template node.
2344 static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2345
2346 /// Return the specialization with the provided arguments if it exists,
2347 /// otherwise return the insertion point.
2349 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2350
2351 /// Insert the specified specialization knowing that it is not already
2352 /// in. InsertPos must be obtained from findSpecialization.
2353 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2354
2356 return cast<ClassTemplateDecl>(
2358 }
2360 return cast<ClassTemplateDecl>(
2362 }
2363
2364 /// Retrieve the previous declaration of this class template, or
2365 /// nullptr if no such declaration exists.
2367 return cast_or_null<ClassTemplateDecl>(
2368 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2369 }
2371 return cast_or_null<ClassTemplateDecl>(
2372 static_cast<const RedeclarableTemplateDecl *>(
2373 this)->getPreviousDecl());
2374 }
2375
2377 return cast<ClassTemplateDecl>(
2378 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2379 }
2381 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2382 }
2383
2385 return cast_or_null<ClassTemplateDecl>(
2387 }
2388
2389 /// Return the partial specialization with the provided arguments if it
2390 /// exists, otherwise return the insertion point.
2393 TemplateParameterList *TPL, void *&InsertPos);
2394
2395 /// Insert the specified partial specialization knowing that it is not
2396 /// already in. InsertPos must be obtained from findPartialSpecialization.
2398 void *InsertPos);
2399
2400 /// Retrieve the partial specializations as an ordered list.
2403
2404 /// Find a class template partial specialization with the given
2405 /// type T.
2406 ///
2407 /// \param T a dependent type that names a specialization of this class
2408 /// template.
2409 ///
2410 /// \returns the class template partial specialization that exactly matches
2411 /// the type \p T, or nullptr if no such partial specialization exists.
2413
2414 /// Find a class template partial specialization which was instantiated
2415 /// from the given member partial specialization.
2416 ///
2417 /// \param D a member class template partial specialization.
2418 ///
2419 /// \returns the class template partial specialization which was instantiated
2420 /// from the given member partial specialization, or nullptr if no such
2421 /// partial specialization exists.
2425
2426 /// Retrieve the template specialization type of the
2427 /// injected-class-name for this class template.
2428 ///
2429 /// The injected-class-name for a class template \c X is \c
2430 /// X<template-args>, where \c template-args is formed from the
2431 /// template arguments that correspond to the template parameters of
2432 /// \c X. For example:
2433 ///
2434 /// \code
2435 /// template<typename T, int N>
2436 /// struct array {
2437 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2438 /// };
2439 /// \endcode
2441
2443 using spec_range = llvm::iterator_range<spec_iterator>;
2444
2446 return spec_range(spec_begin(), spec_end());
2447 }
2448
2450 return makeSpecIterator(getSpecializations(), false);
2451 }
2452
2454 return makeSpecIterator(getSpecializations(), true);
2455 }
2456
2457 // Implement isa/cast/dyncast support
2458 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2459 static bool classofKind(Kind K) { return K == ClassTemplate; }
2460};
2461
2462/// Declaration of a friend template.
2463///
2464/// For example:
2465/// \code
2466/// template <typename T> class A {
2467/// friend class MyVector<T>; // not a friend template
2468/// template <typename U> friend class B; // not a friend template
2469/// template <typename U> friend class Foo<T>::Nested; // friend template
2470/// };
2471/// \endcode
2472///
2473/// \note This class is not currently in use. All of the above
2474/// will yield a FriendDecl, not a FriendTemplateDecl.
2475class FriendTemplateDecl : public Decl {
2476 virtual void anchor();
2477
2478public:
2479 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2480
2481private:
2482 // The number of template parameters; always non-zero.
2483 unsigned NumParams = 0;
2484
2485 // The parameter list.
2486 TemplateParameterList **Params = nullptr;
2487
2488 // The declaration that's a friend of this class.
2489 FriendUnion Friend;
2490
2491 // Location of the 'friend' specifier.
2492 SourceLocation FriendLoc;
2493
2495 TemplateParameterList **Params, unsigned NumParams,
2496 FriendUnion Friend, SourceLocation FriendLoc)
2497 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2498 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2499
2500 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2501
2502public:
2503 friend class ASTDeclReader;
2504
2505 static FriendTemplateDecl *
2506 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2508 SourceLocation FriendLoc);
2509
2510 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2511
2512 /// If this friend declaration names a templated type (or
2513 /// a dependent member type of a templated type), return that
2514 /// type; otherwise return null.
2516 return Friend.dyn_cast<TypeSourceInfo*>();
2517 }
2518
2519 /// If this friend declaration names a templated function (or
2520 /// a member function of a templated type), return that type;
2521 /// otherwise return null.
2523 return Friend.dyn_cast<NamedDecl*>();
2524 }
2525
2526 /// Retrieves the location of the 'friend' keyword.
2528 return FriendLoc;
2529 }
2530
2532 assert(i <= NumParams);
2533 return Params[i];
2534 }
2535
2536 unsigned getNumTemplateParameters() const {
2537 return NumParams;
2538 }
2539
2540 // Implement isa/cast/dyncast/etc.
2541 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2542 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2543};
2544
2545/// Declaration of an alias template.
2546///
2547/// For example:
2548/// \code
2549/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2550/// \endcode
2552protected:
2554
2557 NamedDecl *Decl)
2558 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2559 Decl) {}
2560
2561 CommonBase *newCommon(ASTContext &C) const override;
2562
2564 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2565 }
2566
2567public:
2568 friend class ASTDeclReader;
2569 friend class ASTDeclWriter;
2570
2571 /// Get the underlying function declaration of the template.
2573 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2574 }
2575
2576
2578 return cast<TypeAliasTemplateDecl>(
2580 }
2582 return cast<TypeAliasTemplateDecl>(
2584 }
2585
2586 /// Retrieve the previous declaration of this function template, or
2587 /// nullptr if no such declaration exists.
2589 return cast_or_null<TypeAliasTemplateDecl>(
2590 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2591 }
2593 return cast_or_null<TypeAliasTemplateDecl>(
2594 static_cast<const RedeclarableTemplateDecl *>(
2595 this)->getPreviousDecl());
2596 }
2597
2599 return cast_or_null<TypeAliasTemplateDecl>(
2601 }
2602
2603 /// Create a function template node.
2606 DeclarationName Name,
2607 TemplateParameterList *Params,
2608 NamedDecl *Decl);
2609
2610 /// Create an empty alias template node.
2612
2613 // Implement isa/cast/dyncast support
2614 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2615 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2616};
2617
2618/// Declaration of a function specialization at template class scope.
2619///
2620/// For example:
2621/// \code
2622/// template <class T>
2623/// class A {
2624/// template <class U> void foo(U a) { }
2625/// template<> void foo(int a) { }
2626/// }
2627/// \endcode
2628///
2629/// "template<> foo(int a)" will be saved in Specialization as a normal
2630/// CXXMethodDecl. Then during an instantiation of class A, it will be
2631/// transformed into an actual function specialization.
2632///
2633/// FIXME: This is redundant; we could store the same information directly on
2634/// the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo.
2636 CXXMethodDecl *Specialization;
2637 const ASTTemplateArgumentListInfo *TemplateArgs;
2638
2641 const ASTTemplateArgumentListInfo *TemplArgs)
2642 : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
2643 Specialization(FD), TemplateArgs(TemplArgs) {}
2644
2646 : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2647
2648 virtual void anchor();
2649
2650public:
2651 friend class ASTDeclReader;
2652 friend class ASTDeclWriter;
2653
2655 bool hasExplicitTemplateArgs() const { return TemplateArgs; }
2657 return TemplateArgs;
2658 }
2659
2662 bool HasExplicitTemplateArgs,
2663 const TemplateArgumentListInfo &TemplateArgs) {
2664 return new (C, DC) ClassScopeFunctionSpecializationDecl(
2665 DC, Loc, FD,
2666 HasExplicitTemplateArgs
2667 ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs)
2668 : nullptr);
2669 }
2670
2672 CreateDeserialized(ASTContext &Context, unsigned ID);
2673
2674 // Implement isa/cast/dyncast/etc.
2675 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2676
2677 static bool classofKind(Kind K) {
2678 return K == Decl::ClassScopeFunctionSpecialization;
2679 }
2680};
2681
2682/// Represents a variable template specialization, which refers to
2683/// a variable template with a given set of template arguments.
2684///
2685/// Variable template specializations represent both explicit
2686/// specializations of variable templates, as in the example below, and
2687/// implicit instantiations of variable templates.
2688///
2689/// \code
2690/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2691///
2692/// template<>
2693/// constexpr float pi<float>; // variable template specialization pi<float>
2694/// \endcode
2696 public llvm::FoldingSetNode {
2697
2698 /// Structure that stores information about a variable template
2699 /// specialization that was instantiated from a variable template partial
2700 /// specialization.
2701 struct SpecializedPartialSpecialization {
2702 /// The variable template partial specialization from which this
2703 /// variable template specialization was instantiated.
2704 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2705
2706 /// The template argument list deduced for the variable template
2707 /// partial specialization itself.
2708 const TemplateArgumentList *TemplateArgs;
2709 };
2710
2711 /// The template that this specialization specializes.
2712 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2713 SpecializedTemplate;
2714
2715 /// Further info for explicit template specialization/instantiation.
2716 struct ExplicitSpecializationInfo {
2717 /// The type-as-written.
2718 TypeSourceInfo *TypeAsWritten = nullptr;
2719
2720 /// The location of the extern keyword.
2721 SourceLocation ExternLoc;
2722
2723 /// The location of the template keyword.
2724 SourceLocation TemplateKeywordLoc;
2725
2726 ExplicitSpecializationInfo() = default;
2727 };
2728
2729 /// Further info for explicit template specialization/instantiation.
2730 /// Does not apply to implicit specializations.
2731 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
2732
2733 /// The template arguments used to describe this specialization.
2734 const TemplateArgumentList *TemplateArgs;
2735 const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
2736
2737 /// The point where this template was instantiated (if any).
2738 SourceLocation PointOfInstantiation;
2739
2740 /// The kind of specialization this declaration refers to.
2741 /// Really a value of type TemplateSpecializationKind.
2742 unsigned SpecializationKind : 3;
2743
2744 /// Whether this declaration is a complete definition of the
2745 /// variable template specialization. We can't otherwise tell apart
2746 /// an instantiated declaration from an instantiated definition with
2747 /// no initializer.
2748 unsigned IsCompleteDefinition : 1;
2749
2750protected:
2752 SourceLocation StartLoc, SourceLocation IdLoc,
2753 VarTemplateDecl *SpecializedTemplate,
2754 QualType T, TypeSourceInfo *TInfo,
2755 StorageClass S,
2757
2758 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2759
2760public:
2761 friend class ASTDeclReader;
2762 friend class ASTDeclWriter;
2763 friend class VarDecl;
2764
2766 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2767 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2768 TypeSourceInfo *TInfo, StorageClass S,
2771 unsigned ID);
2772
2773 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2774 bool Qualified) const override;
2775
2777 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2778 return cast<VarTemplateSpecializationDecl>(Recent);
2779 }
2780
2781 /// Retrieve the template that this specialization specializes.
2783
2784 /// Retrieve the template arguments of the variable template
2785 /// specialization.
2786 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2787
2788 // TODO: Always set this when creating the new specialization?
2789 void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2791
2793 return TemplateArgsInfo;
2794 }
2795
2796 /// Determine the kind of specialization that this
2797 /// declaration represents.
2799 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2800 }
2801
2804 }
2805
2807 return isExplicitSpecialization() &&
2808 isa<CXXRecordDecl>(getLexicalDeclContext());
2809 }
2810
2811 /// True if this declaration is an explicit specialization,
2812 /// explicit instantiation declaration, or explicit instantiation
2813 /// definition.
2817 }
2818
2820 SpecializationKind = TSK;
2821 }
2822
2823 /// Get the point of instantiation (if any), or null if none.
2825 return PointOfInstantiation;
2826 }
2827
2829 assert(Loc.isValid() && "point of instantiation must be valid!");
2830 PointOfInstantiation = Loc;
2831 }
2832
2833 void setCompleteDefinition() { IsCompleteDefinition = true; }
2834
2835 /// If this variable template specialization is an instantiation of
2836 /// a template (rather than an explicit specialization), return the
2837 /// variable template or variable template partial specialization from which
2838 /// it was instantiated.
2839 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2842 return llvm::PointerUnion<VarTemplateDecl *,
2844
2846 }
2847
2848 /// Retrieve the variable template or variable template partial
2849 /// specialization which was specialized by this.
2850 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2852 if (const auto *PartialSpec =
2853 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2854 return PartialSpec->PartialSpecialization;
2855
2856 return SpecializedTemplate.get<VarTemplateDecl *>();
2857 }
2858
2859 /// Retrieve the set of template arguments that should be used
2860 /// to instantiate the initializer of the variable template or variable
2861 /// template partial specialization from which this variable template
2862 /// specialization was instantiated.
2863 ///
2864 /// \returns For a variable template specialization instantiated from the
2865 /// primary template, this function will return the same template arguments
2866 /// as getTemplateArgs(). For a variable template specialization instantiated
2867 /// from a variable template partial specialization, this function will the
2868 /// return deduced template arguments for the variable template partial
2869 /// specialization itself.
2871 if (const auto *PartialSpec =
2872 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2873 return *PartialSpec->TemplateArgs;
2874
2875 return getTemplateArgs();
2876 }
2877
2878 /// Note that this variable template specialization is actually an
2879 /// instantiation of the given variable template partial specialization whose
2880 /// template arguments have been deduced.
2882 const TemplateArgumentList *TemplateArgs) {
2883 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2884 "Already set to a variable template partial specialization!");
2885 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2886 PS->PartialSpecialization = PartialSpec;
2887 PS->TemplateArgs = TemplateArgs;
2888 SpecializedTemplate = PS;
2889 }
2890
2891 /// Note that this variable template specialization is an instantiation
2892 /// of the given variable template.
2894 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2895 "Previously set to a variable template partial specialization!");
2896 SpecializedTemplate = TemplDecl;
2897 }
2898
2899 /// Sets the type of this specialization as it was written by
2900 /// the user.
2902 if (!ExplicitInfo)
2903 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2904 ExplicitInfo->TypeAsWritten = T;
2905 }
2906
2907 /// Gets the type of this specialization as it was written by
2908 /// the user, if it was so written.
2910 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2911 }
2912
2913 /// Gets the location of the extern keyword, if present.
2915 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2916 }
2917
2918 /// Sets the location of the extern keyword.
2920 if (!ExplicitInfo)
2921 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2922 ExplicitInfo->ExternLoc = Loc;
2923 }
2924
2925 /// Sets the location of the template keyword.
2927 if (!ExplicitInfo)
2928 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2929 ExplicitInfo->TemplateKeywordLoc = Loc;
2930 }
2931
2932 /// Gets the location of the template keyword, if present.
2934 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2935 }
2936
2937 SourceRange getSourceRange() const override LLVM_READONLY;
2938
2939 void Profile(llvm::FoldingSetNodeID &ID) const {
2940 Profile(ID, TemplateArgs->asArray(), getASTContext());
2941 }
2942
2943 static void Profile(llvm::FoldingSetNodeID &ID,
2944 ArrayRef<TemplateArgument> TemplateArgs,
2945 const ASTContext &Context) {
2946 ID.AddInteger(TemplateArgs.size());
2947 for (const TemplateArgument &TemplateArg : TemplateArgs)
2948 TemplateArg.Profile(ID, Context);
2949 }
2950
2951 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2952
2953 static bool classofKind(Kind K) {
2954 return K >= firstVarTemplateSpecialization &&
2955 K <= lastVarTemplateSpecialization;
2956 }
2957};
2958
2961 /// The list of template parameters
2962 TemplateParameterList *TemplateParams = nullptr;
2963
2964 /// The source info for the template arguments as written.
2965 /// FIXME: redundant with TypeAsWritten?
2966 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2967
2968 /// The variable template partial specialization from which this
2969 /// variable template partial specialization was instantiated.
2970 ///
2971 /// The boolean value will be true to indicate that this variable template
2972 /// partial specialization was specialized at this level.
2973 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2974 InstantiatedFromMember;
2975
2977 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2979 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2981 const ASTTemplateArgumentListInfo *ArgInfos);
2982
2984 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2985 Context),
2986 InstantiatedFromMember(nullptr, false) {}
2987
2988 void anchor() override;
2989
2990public:
2991 friend class ASTDeclReader;
2992 friend class ASTDeclWriter;
2993
2995 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2997 VarTemplateDecl *SpecializedTemplate, QualType T,
2999 const TemplateArgumentListInfo &ArgInfos);
3000
3002 unsigned ID);
3003
3005 return cast<VarTemplatePartialSpecializationDecl>(
3006 static_cast<VarTemplateSpecializationDecl *>(
3007 this)->getMostRecentDecl());
3008 }
3009
3010 /// Get the list of template parameters
3012 return TemplateParams;
3013 }
3014
3015 /// Get the template arguments as written.
3017 return ArgsAsWritten;
3018 }
3019
3020 /// \brief All associated constraints of this partial specialization,
3021 /// including the requires clause and any constraints derived from
3022 /// constrained-parameters.
3023 ///
3024 /// The constraints in the resulting list are to be treated as if in a
3025 /// conjunction ("and").
3027 TemplateParams->getAssociatedConstraints(AC);
3028 }
3029
3031 return TemplateParams->hasAssociatedConstraints();
3032 }
3033
3034 /// \brief Retrieve the member variable template partial specialization from
3035 /// which this particular variable template partial specialization was
3036 /// instantiated.
3037 ///
3038 /// \code
3039 /// template<typename T>
3040 /// struct Outer {
3041 /// template<typename U> U Inner;
3042 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
3043 /// };
3044 ///
3045 /// template int* Outer<float>::Inner<int*>;
3046 /// \endcode
3047 ///
3048 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
3049 /// end up instantiating the partial specialization
3050 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
3051 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
3052 /// \c Outer<float>::Inner<U*>, this function would return
3053 /// \c Outer<T>::Inner<U*>.
3055 const auto *First =
3056 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3057 return First->InstantiatedFromMember.getPointer();
3058 }
3059
3060 void
3062 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3063 First->InstantiatedFromMember.setPointer(PartialSpec);
3064 }
3065
3066 /// Determines whether this variable template partial specialization
3067 /// was a specialization of a member partial specialization.
3068 ///
3069 /// In the following example, the member template partial specialization
3070 /// \c X<int>::Inner<T*> is a member specialization.
3071 ///
3072 /// \code
3073 /// template<typename T>
3074 /// struct X {
3075 /// template<typename U> U Inner;
3076 /// template<typename U> U* Inner<U*> = (U*)(0);
3077 /// };
3078 ///
3079 /// template<> template<typename T>
3080 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
3081 /// \endcode
3083 const auto *First =
3084 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3085 return First->InstantiatedFromMember.getInt();
3086 }
3087
3088 /// Note that this member template is a specialization.
3090 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3091 assert(First->InstantiatedFromMember.getPointer() &&
3092 "Only member templates can be member template specializations");
3093 return First->InstantiatedFromMember.setInt(true);
3094 }
3095
3096 SourceRange getSourceRange() const override LLVM_READONLY;
3097
3098 void Profile(llvm::FoldingSetNodeID &ID) const {
3100 getASTContext());
3101 }
3102
3103 static void
3104 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3105 TemplateParameterList *TPL, const ASTContext &Context);
3106
3107 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3108
3109 static bool classofKind(Kind K) {
3110 return K == VarTemplatePartialSpecialization;
3111 }
3112};
3113
3114/// Declaration of a variable template.
3116protected:
3117 /// Data that is common to all of the declarations of a given
3118 /// variable template.
3120 /// The variable template specializations for this variable
3121 /// template, including explicit specializations and instantiations.
3122 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3123
3124 /// The variable template partial specializations for this variable
3125 /// template.
3126 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3128
3129 Common() = default;
3130 };
3131
3132 /// Retrieve the set of specializations of this variable template.
3133 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3134 getSpecializations() const;
3135
3136 /// Retrieve the set of partial specializations of this class
3137 /// template.
3138 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3140
3143 NamedDecl *Decl)
3144 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3145
3146 CommonBase *newCommon(ASTContext &C) const override;
3147
3149 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3150 }
3151
3152public:
3153 friend class ASTDeclReader;
3154 friend class ASTDeclWriter;
3155
3156 /// Load any lazily-loaded specializations from the external source.
3157 void LoadLazySpecializations() const;
3158
3159 /// Get the underlying variable declarations of the template.
3161 return static_cast<VarDecl *>(TemplatedDecl);
3162 }
3163
3164 /// Returns whether this template declaration defines the primary
3165 /// variable pattern.
3168 }
3169
3171
3172 /// Create a variable template node.
3175 TemplateParameterList *Params,
3176 VarDecl *Decl);
3177
3178 /// Create an empty variable template node.
3179 static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
3180
3181 /// Return the specialization with the provided arguments if it exists,
3182 /// otherwise return the insertion point.
3184 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3185
3186 /// Insert the specified specialization knowing that it is not already
3187 /// in. InsertPos must be obtained from findSpecialization.
3188 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3189
3191 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3192 }
3194 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3195 }
3196
3197 /// Retrieve the previous declaration of this variable template, or
3198 /// nullptr if no such declaration exists.
3200 return cast_or_null<VarTemplateDecl>(
3201 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3202 }
3204 return cast_or_null<VarTemplateDecl>(
3205 static_cast<const RedeclarableTemplateDecl *>(
3206 this)->getPreviousDecl());
3207 }
3208
3210 return cast<VarTemplateDecl>(
3211 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3212 }
3214 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3215 }
3216
3218 return cast_or_null<VarTemplateDecl>(
3220 }
3221
3222 /// Return the partial specialization with the provided arguments if it
3223 /// exists, otherwise return the insertion point.
3226 TemplateParameterList *TPL, void *&InsertPos);
3227
3228 /// Insert the specified partial specialization knowing that it is not
3229 /// already in. InsertPos must be obtained from findPartialSpecialization.
3231 void *InsertPos);
3232
3233 /// Retrieve the partial specializations as an ordered list.
3236
3237 /// Find a variable template partial specialization which was
3238 /// instantiated
3239 /// from the given member partial specialization.
3240 ///
3241 /// \param D a member variable template partial specialization.
3242 ///
3243 /// \returns the variable template partial specialization which was
3244 /// instantiated
3245 /// from the given member partial specialization, or nullptr if no such
3246 /// partial specialization exists.
3249
3251 using spec_range = llvm::iterator_range<spec_iterator>;
3252
3254 return spec_range(spec_begin(), spec_end());
3255 }
3256
3258 return makeSpecIterator(getSpecializations(), false);
3259 }
3260
3262 return makeSpecIterator(getSpecializations(), true);
3263 }
3264
3265 // Implement isa/cast/dyncast support
3266 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3267 static bool classofKind(Kind K) { return K == VarTemplate; }
3268};
3269
3270/// Declaration of a C++20 concept.
3271class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3272protected:
3274
3277 : TemplateDecl(Concept, DC, L, Name, Params),
3279public:
3282 TemplateParameterList *Params,
3284 static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID);
3285
3287 return ConstraintExpr;
3288 }
3289
3290 SourceRange getSourceRange() const override LLVM_READONLY {
3291 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3293 }
3294
3295 bool isTypeConcept() const {
3296 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3297 }
3298
3300 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3301 }
3303 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3304 }
3305
3306 // Implement isa/cast/dyncast/etc.
3307 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3308 static bool classofKind(Kind K) { return K == Concept; }
3309
3310 friend class ASTReader;
3311 friend class ASTDeclReader;
3312 friend class ASTDeclWriter;
3313};
3314
3315// An implementation detail of ConceptSpecialicationExpr that holds the template
3316// arguments, so we can later use this to reconstitute the template arguments
3317// during constraint checking.
3319 : public Decl,
3320 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3321 TemplateArgument> {
3322 unsigned NumTemplateArgs;
3323
3325 ArrayRef<TemplateArgument> ConvertedArgs);
3326 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3327
3328public:
3331 ArrayRef<TemplateArgument> ConvertedArgs);
3333 CreateDeserialized(const ASTContext &C, unsigned ID,
3334 unsigned NumTemplateArgs);
3335
3337 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3338 NumTemplateArgs);
3339 }
3341
3342 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3343 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3344
3346 friend class ASTDeclReader;
3347};
3348
3349/// A template parameter object.
3350///
3351/// Template parameter objects represent values of class type used as template
3352/// arguments. There is one template parameter object for each such distinct
3353/// value used as a template argument across the program.
3354///
3355/// \code
3356/// struct A { int x, y; };
3357/// template<A> struct S;
3358/// S<A{1, 2}> s1;
3359/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3360/// \endcode
3362 public Mergeable<TemplateParamObjectDecl>,
3363 public llvm::FoldingSetNode {
3364private:
3365 /// The value of this template parameter object.
3366 APValue Value;
3367
3369 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3370 T),
3371 Value(V) {}
3372
3373 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3374 const APValue &V);
3375 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3376 unsigned ID);
3377
3378 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3379 /// create these.
3380 friend class ASTContext;
3381 friend class ASTReader;
3382 friend class ASTDeclReader;
3383
3384public:
3385 /// Print this template parameter object in a human-readable format.
3386 void printName(llvm::raw_ostream &OS,
3387 const PrintingPolicy &Policy) const override;
3388
3389 /// Print this object as an equivalent expression.
3390 void printAsExpr(llvm::raw_ostream &OS) const;
3391 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3392
3393 /// Print this object as an initializer suitable for a variable of the
3394 /// object's type.
3395 void printAsInit(llvm::raw_ostream &OS) const;
3396 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3397
3398 const APValue &getValue() const { return Value; }
3399
3400 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3401 const APValue &V) {
3402 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3403 V.Profile(ID);
3404 }
3405 void Profile(llvm::FoldingSetNodeID &ID) {
3406 Profile(ID, getType(), getValue());
3407 }
3408
3410 return getFirstDecl();
3411 }
3413 return getFirstDecl();
3414 }
3415
3416 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3417 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3418};
3419
3421 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3422 return PD;
3423 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3424 return PD;
3425 return P.get<TemplateTemplateParmDecl *>();
3426}
3427
3429 auto *TD = dyn_cast<TemplateDecl>(D);
3430 return TD && (isa<ClassTemplateDecl>(TD) ||
3431 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3432 isa<TypeAliasTemplateDecl>(TD) ||
3433 isa<TemplateTemplateParmDecl>(TD))
3434 ? TD
3435 : nullptr;
3436}
3437
3438/// Check whether the template parameter is a pack expansion, and if so,
3439/// determine the number of parameters produced by that expansion. For instance:
3440///
3441/// \code
3442/// template<typename ...Ts> struct A {
3443/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3444/// };
3445/// \endcode
3446///
3447/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3448/// is not a pack expansion, so returns an empty Optional.
3449inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3450 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3451 if (TTP->isExpandedParameterPack())
3452 return TTP->getNumExpansionParameters();
3453 }
3454
3455 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3456 if (NTTP->isExpandedParameterPack())
3457 return NTTP->getNumExpansionTypes();
3458 }
3459
3460 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3461 if (TTP->isExpandedParameterPack())
3462 return TTP->getNumExpansionTemplateParameters();
3463 }
3464
3465 return std::nullopt;
3466}
3467
3468/// Internal helper used by Subst* nodes to retrieve the parameter list
3469/// for their AssociatedDecl.
3470TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3471
3472} // namespace clang
3473
3474#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3230
int Id
Definition: ASTDiff.cpp:190
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
__device__ int
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
bool isConstrained() const
Definition: Type.h:5301
Represents the builtin template declaration which is used to implement __make_integer_seq and other b...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
BuiltinTemplateKind getBuiltinTemplateKind() const
static BuiltinTemplateDecl * Create(const ASTContext &C, DeclContext *DC, DeclarationName Name, BuiltinTemplateKind BTK)
static bool classof(const Decl *D)
static bool classofKind(Kind K)
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2035
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
CXXRecordDecl * getMostRecentNonInjectedDecl()
Definition: DeclCXX.h:537
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition: DeclCXX.cpp:1866
Declaration of a function specialization at template class scope.
static ClassScopeFunctionSpecializationDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, bool HasExplicitTemplateArgs, const TemplateArgumentListInfo &TemplateArgs)
static ClassScopeFunctionSpecializationDecl * CreateDeserialized(ASTContext &Context, unsigned ID)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
ClassTemplateDecl * getMostRecentDecl()
spec_iterator spec_begin() const
spec_iterator spec_end() const
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty class template node.
static bool classofKind(Kind K)
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
llvm::iterator_range< spec_iterator > spec_range
static bool classof(const Decl *D)
const ClassTemplateDecl * getMostRecentDecl() const
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
const ClassTemplateDecl * getCanonicalDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
void setCommonPtr(Common *C)
spec_range specializations() const
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
bool isMemberSpecialization()
Determines whether this class template partial specialization template was a specialization of a memb...
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
void setMemberSpecialization()
Note that this member template is a specialization.
QualType getInjectedSpecializationType() const
Retrieves the injected specialization type for this partial specialization.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Get the template arguments as written.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
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)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?...
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setTypeAsWritten(TypeSourceInfo *T)
Sets the type of this specialization as it was written by the user.
void setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
static bool classof(const Decl *D)
void setSpecializationKind(TemplateSpecializationKind TSK)
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
void setExternLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
static ConceptDecl * CreateDeserialized(ASTContext &C, unsigned ID)
bool isTypeConcept() const
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
static bool classof(const Decl *D)
const ConceptDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1402
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Decl()=delete
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:576
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:86
SourceLocation getLocation() const
Definition: DeclBase.h:432
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:886
Kind getKind() const
Definition: DeclBase.h:435
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:420
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:765
Storage for a default argument.
Definition: DeclTemplate.h:315
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
Definition: DeclTemplate.h:376
bool isSet() const
Determine whether there is a default argument for this parameter.
Definition: DeclTemplate.h:342
ArgType get() const
Get the default argument's value.
Definition: DeclTemplate.h:350
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:370
void clear()
Remove the default argument, even if it was inherited.
Definition: DeclTemplate.h:395
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
Definition: DeclTemplate.h:361
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
Definition: DeclTemplate.h:346
Provides information about a dependent function-template specialization declaration.
Definition: DeclTemplate.h:698
unsigned getNumTemplates() const
Returns the number of function templates that this might be a specialization of.
Definition: DeclTemplate.h:728
const TemplateArgumentLoc * getTemplateArgs() const
Returns the explicit template arguments that were given.
Definition: DeclTemplate.h:737
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: DeclTemplate.h:744
const TemplateArgumentLoc & getTemplateArg(unsigned I) const
Returns the nth template argument.
Definition: DeclTemplate.h:749
unsigned getNumTemplateArgs() const
Returns the number of explicit template arguments that were given.
Definition: DeclTemplate.h:742
FunctionTemplateDecl * getTemplate(unsigned I) const
Returns the i'th template candidate.
Definition: DeclTemplate.h:731
static DependentFunctionTemplateSpecializationInfo * Create(ASTContext &Context, const UnresolvedSetImpl &Templates, const TemplateArgumentListInfo &TemplateArgs)
Definition: Decl.cpp:4070
This represents one expression.
Definition: Expr.h:110
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Definition: DeclTemplate.h:218
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Definition: DeclTemplate.h:225
Declaration of a friend template.
static bool classof(const Decl *D)
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
NamedDecl * getFriendDecl() const
If this friend declaration names a templated function (or a member function of a templated type),...
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
TemplateParameterList * getTemplateParameterList(unsigned i) const
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
static bool classofKind(Kind K)
unsigned getNumTemplateParameters() const
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
TypeSourceInfo * getFriendType() const
If this friend declaration names a templated type (or a dependent member type of a templated type),...
Represents a function declaration or definition.
Definition: Decl.h:1917
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2216
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
spec_iterator spec_end() const
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty function template node.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
spec_range specializations() const
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const FunctionTemplateDecl * getMostRecentDecl() const
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:482
const TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
Definition: DeclTemplate.h:496
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:558
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
Definition: DeclTemplate.h:620
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
Definition: DeclTemplate.h:538
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
Definition: DeclTemplate.h:609
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:500
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
Definition: DeclTemplate.h:569
void Profile(llvm::FoldingSetNodeID &ID)
Definition: DeclTemplate.h:615
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
Definition: DeclTemplate.h:504
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
Definition: DeclTemplate.h:535
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:541
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
Definition: DeclTemplate.h:575
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
Definition: DeclTemplate.h:552
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, unsigned ID, unsigned NumTemplateArgs)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
static bool classof(const Decl *D)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:631
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:662
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:653
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
Definition: DeclTemplate.h:671
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
Definition: DeclTemplate.h:641
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Definition: DeclTemplate.h:676
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
Definition: DeclTemplate.h:650
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
Definition: Redeclarable.h:314
TemplateParamObjectDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:320
This represents a decl that may have a name.
Definition: Decl.h:247
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
const DefArgStorage & getDefaultArgStorage() const
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
static bool classofKind(Kind K)
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
static bool classof(const Decl *D)
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
void setDefaultArgument(Expr *DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool hasPlaceholderTypeConstraint() const
Determine whether this non-type template parameter's type has a placeholder with a type-constraint.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setPlaceholderTypeConstraint(Expr *E)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm)
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID, bool HasTypeConstraint)
Represents a pack expansion of types.
Definition: Type.h:5873
A (possibly-)qualified type.
Definition: Type.h:736
QualType getCanonicalType() const
Definition: Type.h:6716
void * getAsOpaquePtr() const
Definition: Type.h:783
Declaration of a redeclarable template.
Definition: DeclTemplate.h:766
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
Definition: DeclTemplate.h:818
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:873
redeclarable_base::redecl_iterator redecl_iterator
Definition: DeclTemplate.h:975
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:910
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
const RedeclarableTemplateDecl * getCanonicalDecl() const
Definition: DeclTemplate.h:888
redeclarable_base::redecl_range redecl_range
Definition: DeclTemplate.h:974
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:863
static bool classof(const Decl *D)
Definition: DeclTemplate.h:985
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
Definition: DeclTemplate.h:957
static bool classofKind(Kind K)
Definition: DeclTemplate.h:987
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:885
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
Definition: DeclTemplate.h:915
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
Definition: DeclTemplate.h:961
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Provides common interface for the Decls that can be redeclared.
Definition: Redeclarable.h:84
RedeclarableTemplateDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:216
RedeclarableTemplateDecl * getNextRedeclaration() const
Definition: Redeclarable.h:189
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:292
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:223
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:296
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:356
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:349
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3552
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
A template argument list.
Definition: DeclTemplate.h:240
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
Definition: DeclTemplate.h:301
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:289
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
TemplateArgumentList(const TemplateArgumentList *Other)
Produces a shallow copy of the given template argument list.
Definition: DeclTemplate.h:279
OnStackType
Type used to indicate that the template argument list itself is a stack object.
Definition: DeclTemplate.h:260
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:298
TemplateArgumentList(OnStackType, ArrayRef< TemplateArgument > Args)
Construct a new, temporary template argument list on the stack.
Definition: DeclTemplate.h:271
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:283
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:292
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:60
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:409
NamedDecl * TemplatedDecl
Definition: DeclTemplate.h:459
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:460
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
Definition: DeclTemplate.h:468
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:441
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:453
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
Definition: DeclTemplate.h:419
void setTemplateParameters(TemplateParameterList *TParams)
Definition: DeclTemplate.h:463
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
static bool classof(const Decl *D)
Definition: DeclTemplate.h:447
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:428
static bool classofKind(Kind K)
Definition: DeclTemplate.h:449
A template parameter object.
TemplateParamObjectDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const TemplateParamObjectDecl * getCanonicalDecl() const
void Profile(llvm::FoldingSetNodeID &ID)
const APValue & getValue() const
static bool classof(const Decl *D)
static void Profile(llvm::FoldingSetNodeID &ID, QualType T, const APValue &V)
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
static bool classofKind(Kind K)
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
const_iterator end() const
Definition: DeclTemplate.h:131
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:140
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:199
const_iterator begin() const
Definition: DeclTemplate.h:129
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
const Expr * getRequiresClause() const
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:181
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
size_t numTrailingObjects(OverloadToken< Expr * >) const
Definition: DeclTemplate.h:104
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
Definition: DeclTemplate.h:168
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
NamedDecl *const * const_iterator
Iterates through the template parameters in this list.
Definition: DeclTemplate.h:126
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:176
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
Definition: DeclTemplate.h:197
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
Definition: DeclTemplate.h:144
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
Definition: DeclTemplate.h:196
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
Definition: DeclTemplate.h:100
TemplateParameterList(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
void print(raw_ostream &Out, const ASTContext &Context, bool OmitTemplateKW=false) const
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:135
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:195
ArrayRef< const NamedDecl * > asArray() const
Definition: DeclTemplate.h:136
Defines the position of a template parameter within a template parameter list.
static constexpr unsigned MaxPosition
static constexpr unsigned MaxDepth
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
void setPosition(unsigned P)
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
TemplateParmPosition(unsigned D, unsigned P)
unsigned getDepth() const
Get the nesting depth of the template parameter.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TemplateParameterList * getExpansionTemplateParameters(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
unsigned getNumExpansionTemplateParameters() const
Retrieves the number of expansion template parameters in an expanded parameter pack.
const DefArgStorage & getDefaultArgStorage() const
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID)
static bool classof(const Decl *D)
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
void setInheritedDefaultArgument(const ASTContext &C, TemplateTemplateParmDecl *Prev)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
static bool classofKind(Kind K)
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params)
void removeDefaultArgument()
Removes the default argument of this template parameter.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
QualType getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
void setInheritedDefaultArgument(const ASTContext &C, TemplateTypeParmDecl *Prev)
Set that this default argument was inherited from another parameter.
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
TypeSourceInfo * getDefaultArgumentInfo() const
Retrieves the default argument's source information, if any.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isExpandedParameterPack() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, unsigned ID)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setDefaultArgument(TypeSourceInfo *DefArg)
Set the default argument for this template parameter.
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const DefArgStorage & getDefaultArgStorage() const
unsigned getNumExpansionParameters() const
Retrieves the number of parameters in an expanded parameter pack.
static bool classofKind(Kind K)
static bool classof(const Decl *D)
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
void setTypeConstraint(NestedNameSpecifierLoc NNS, DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD, const ASTTemplateArgumentListInfo *ArgsAsWritten, Expr *ImmediatelyDeclaredConstraint)
void setDeclaredWithTypename(bool withTypename)
Set whether this template type parameter was declared with the 'typename' or 'class' keyword.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3426
Declaration of an alias template.
static bool classof(const Decl *D)
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty alias template node.
TypeAliasTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const TypeAliasTemplateDecl * getPreviousDecl() const
TypeAliasTemplateDecl * getInstantiatedFromMemberTemplate() const
const TypeAliasTemplateDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
TypeAliasTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
TypeAliasDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Represents a declaration of a type.
Definition: Decl.h:3262
const Type * getTypeForDecl() const
Definition: Decl.h:3286
A container of type source information.
Definition: Type.h:6635
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6646
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2434
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7430
A set of unresolved declarations.
Definition: UnresolvedSet.h:61
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:701
QualType getType() const
Definition: Decl.h:712
Represents a variable declaration or definition.
Definition: Decl.h:913
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2206
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition: Decl.cpp:2695
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
static VarTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty variable template node.
spec_range specializations() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Get the template arguments as written.
void setMemberSpecialization()
Note that this member template is a specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
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)
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization()
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
VarTemplatePartialSpecializationDecl * getMostRecentDecl()
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
void setExternLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
static bool classof(const Decl *D)
void setTypeAsWritten(TypeSourceInfo *T)
Sets the type of this specialization as it was written by the user.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this variable template specialization is actually an instantiation of the given variable te...
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
Definition: