clang 18.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 LLVM_PREFERRED_TYPE(bool)
87 unsigned ContainsUnexpandedParameterPack : 1;
88
89 /// Whether this template parameter list has a requires clause.
90 LLVM_PREFERRED_TYPE(bool)
91 unsigned HasRequiresClause : 1;
92
93 /// Whether any of the template parameters has constrained-parameter
94 /// constraint-expression.
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned HasConstrainedParameters : 1;
97
98protected:
100 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
101 SourceLocation RAngleLoc, Expr *RequiresClause);
102
103 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
104 return NumParams;
105 }
106
107 size_t numTrailingObjects(OverloadToken<Expr *>) const {
108 return HasRequiresClause ? 1 : 0;
109 }
110
111public:
112 template <size_t N, bool HasRequiresClause>
115
117 SourceLocation TemplateLoc,
118 SourceLocation LAngleLoc,
120 SourceLocation RAngleLoc,
121 Expr *RequiresClause);
122
123 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
124
125 /// Iterates through the template parameters in this list.
126 using iterator = NamedDecl **;
127
128 /// Iterates through the template parameters in this list.
129 using const_iterator = NamedDecl * const *;
130
131 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
132 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
133 iterator end() { return begin() + NumParams; }
134 const_iterator end() const { return begin() + NumParams; }
135
136 unsigned size() const { return NumParams; }
137
140 return llvm::ArrayRef(begin(), size());
141 }
142
143 NamedDecl* getParam(unsigned Idx) {
144 assert(Idx < size() && "Template parameter index out-of-range");
145 return begin()[Idx];
146 }
147 const NamedDecl* getParam(unsigned Idx) const {
148 assert(Idx < size() && "Template parameter index out-of-range");
149 return begin()[Idx];
150 }
151
152 /// Returns the minimum number of arguments needed to form a
153 /// template specialization.
154 ///
155 /// This may be fewer than the number of template parameters, if some of
156 /// the parameters have default arguments or if there is a parameter pack.
157 unsigned getMinRequiredArguments() const;
158
159 /// Get the depth of this template parameter list in the set of
160 /// template parameter lists.
161 ///
162 /// The first template parameter list in a declaration will have depth 0,
163 /// the second template parameter list will have depth 1, etc.
164 unsigned getDepth() const;
165
166 /// Determine whether this template parameter list contains an
167 /// unexpanded parameter pack.
169
170 /// Determine whether this template parameter list contains a parameter pack.
171 bool hasParameterPack() const {
172 for (const NamedDecl *P : asArray())
173 if (P->isParameterPack())
174 return true;
175 return false;
176 }
177
178 /// The constraint-expression of the associated requires-clause.
180 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
181 }
182
183 /// The constraint-expression of the associated requires-clause.
184 const Expr *getRequiresClause() const {
185 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
186 }
187
188 /// \brief All associated constraints derived from this template parameter
189 /// list, including the requires clause and any constraints derived from
190 /// constrained-parameters.
191 ///
192 /// The constraints in the resulting list are to be treated as if in a
193 /// conjunction ("and").
195
197
198 SourceLocation getTemplateLoc() const { return TemplateLoc; }
199 SourceLocation getLAngleLoc() const { return LAngleLoc; }
200 SourceLocation getRAngleLoc() const { return RAngleLoc; }
201
202 SourceRange getSourceRange() const LLVM_READONLY {
203 return SourceRange(TemplateLoc, RAngleLoc);
204 }
205
206 void print(raw_ostream &Out, const ASTContext &Context,
207 bool OmitTemplateKW = false) const;
208 void print(raw_ostream &Out, const ASTContext &Context,
209 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
210
212 const TemplateParameterList *TPL,
213 unsigned Idx);
214};
215
216/// Stores a list of template parameters and the associated
217/// requires-clause (if any) for a TemplateDecl and its derived classes.
218/// Suitable for creating on the stack.
219template <size_t N, bool HasRequiresClause>
221 : public TemplateParameterList::FixedSizeStorageOwner {
222 typename TemplateParameterList::FixedSizeStorage<
223 NamedDecl *, Expr *>::with_counts<
224 N, HasRequiresClause ? 1u : 0u
225 >::type storage;
226
227public:
229 SourceLocation TemplateLoc,
230 SourceLocation LAngleLoc,
232 SourceLocation RAngleLoc,
233 Expr *RequiresClause)
234 : FixedSizeStorageOwner(
235 (assert(N == Params.size()),
236 assert(HasRequiresClause == (RequiresClause != nullptr)),
237 new (static_cast<void *>(&storage)) TemplateParameterList(C,
238 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
239};
240
241/// A template argument list.
243 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
244 /// The template argument list.
245 const TemplateArgument *Arguments;
246
247 /// The number of template arguments in this template
248 /// argument list.
249 unsigned NumArguments;
250
251 // Constructs an instance with an internal Argument list, containing
252 // a copy of the Args array. (Called by CreateCopy)
254
255public:
257
260
261 /// Type used to indicate that the template argument list itself is a
262 /// stack object. It does not own its template arguments.
264
265 /// Create a new template argument list that copies the given set of
266 /// template arguments.
269
270 /// Construct a new, temporary template argument list on the stack.
271 ///
272 /// The template argument list does not own the template arguments
273 /// provided.
275 : Arguments(Args.data()), NumArguments(Args.size()) {}
276
277 /// Produces a shallow copy of the given template argument list.
278 ///
279 /// This operation assumes that the input argument list outlives it.
280 /// This takes the list as a pointer to avoid looking like a copy
281 /// constructor, since this really isn't safe to use that way.
283 : Arguments(Other->data()), NumArguments(Other->size()) {}
284
285 /// Retrieve the template argument at a given index.
286 const TemplateArgument &get(unsigned Idx) const {
287 assert(Idx < NumArguments && "Invalid template argument index");
288 return data()[Idx];
289 }
290
291 /// Retrieve the template argument at a given index.
292 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
293
294 /// Produce this as an array ref.
296 return llvm::ArrayRef(data(), size());
297 }
298
299 /// Retrieve the number of template arguments in this
300 /// template argument list.
301 unsigned size() const { return NumArguments; }
302
303 /// Retrieve a pointer to the template argument list.
304 const TemplateArgument *data() const { return Arguments; }
305};
306
307void *allocateDefaultArgStorageChain(const ASTContext &C);
308
309/// Storage for a default argument. This is conceptually either empty, or an
310/// argument value, or a pointer to a previous declaration that had a default
311/// argument.
312///
313/// However, this is complicated by modules: while we require all the default
314/// arguments for a template to be equivalent, there may be more than one, and
315/// we need to track all the originating parameters to determine if the default
316/// argument is visible.
317template<typename ParmDecl, typename ArgType>
319 /// Storage for both the value *and* another parameter from which we inherit
320 /// the default argument. This is used when multiple default arguments for a
321 /// parameter are merged together from different modules.
322 struct Chain {
323 ParmDecl *PrevDeclWithDefaultArg;
324 ArgType Value;
325 };
326 static_assert(sizeof(Chain) == sizeof(void *) * 2,
327 "non-pointer argument type?");
328
329 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
330
331 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
332 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
333 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
334 Parm = Prev;
335 assert(!Parm->getDefaultArgStorage()
336 .ValueOrInherited.template is<ParmDecl *>() &&
337 "should only be one level of indirection");
338 return Parm;
339 }
340
341public:
342 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
343
344 /// Determine whether there is a default argument for this parameter.
345 bool isSet() const { return !ValueOrInherited.isNull(); }
346
347 /// Determine whether the default argument for this parameter was inherited
348 /// from a previous declaration of the same entity.
349 bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
350
351 /// Get the default argument's value. This does not consider whether the
352 /// default argument is visible.
353 ArgType get() const {
354 const DefaultArgStorage *Storage = this;
355 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
356 Storage = &Prev->getDefaultArgStorage();
357 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
358 return C->Value;
359 return Storage->ValueOrInherited.template get<ArgType>();
360 }
361
362 /// Get the parameter from which we inherit the default argument, if any.
363 /// This is the parameter on which the default argument was actually written.
364 const ParmDecl *getInheritedFrom() const {
365 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
366 return D;
367 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
368 return C->PrevDeclWithDefaultArg;
369 return nullptr;
370 }
371
372 /// Set the default argument.
373 void set(ArgType Arg) {
374 assert(!isSet() && "default argument already set");
375 ValueOrInherited = Arg;
376 }
377
378 /// Set that the default argument was inherited from another parameter.
379 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
380 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
381 if (!isSet())
382 ValueOrInherited = InheritedFrom;
383 else if ([[maybe_unused]] auto *D =
384 ValueOrInherited.template dyn_cast<ParmDecl *>()) {
385 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
386 ValueOrInherited =
387 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
388 } else if (auto *Inherited =
389 ValueOrInherited.template dyn_cast<Chain *>()) {
390 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
391 InheritedFrom));
392 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
393 } else
394 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
395 Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
396 }
397
398 /// Remove the default argument, even if it was inherited.
399 void clear() {
400 ValueOrInherited = ArgType();
401 }
402};
403
404//===----------------------------------------------------------------------===//
405// Kinds of Templates
406//===----------------------------------------------------------------------===//
407
408/// \brief The base class of all kinds of template declarations (e.g.,
409/// class, function, etc.).
410///
411/// The TemplateDecl class stores the list of template parameters and a
412/// reference to the templated scoped declaration: the underlying AST node.
413class TemplateDecl : public NamedDecl {
414 void anchor() override;
415
416protected:
417 // Construct a template decl with name, parameters, and templated element.
420
421 // Construct a template decl with the given name and parameters.
422 // Used when there is no templated element (e.g., for tt-params).
424 TemplateParameterList *Params)
425 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
426
427public:
428 friend class ASTDeclReader;
429 friend class ASTDeclWriter;
430
431 /// Get the list of template parameters
433 return TemplateParams;
434 }
435
436 /// \brief Get the total constraint-expression associated with this template,
437 /// including constraint-expressions derived from the requires-clause,
438 /// trailing requires-clause (for functions and methods) and constrained
439 /// template parameters.
441
442 bool hasAssociatedConstraints() const;
443
444 /// Get the underlying, templated declaration.
446
447 // Should a specialization behave like an alias for another type.
448 bool isTypeAlias() const;
449
450 // Implement isa/cast/dyncast/etc.
451 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
452
453 static bool classofKind(Kind K) {
454 return K >= firstTemplate && K <= lastTemplate;
455 }
456
457 SourceRange getSourceRange() const override LLVM_READONLY {
458 return SourceRange(getTemplateParameters()->getTemplateLoc(),
460 }
461
462protected:
465
466public:
468 TemplateParams = TParams;
469 }
470
471 /// Initialize the underlying templated declaration.
472 void init(NamedDecl *NewTemplatedDecl) {
473 if (TemplatedDecl)
474 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
475 else
476 TemplatedDecl = NewTemplatedDecl;
477 }
478};
479
480/// Provides information about a function template specialization,
481/// which is a FunctionDecl that has been explicitly specialization or
482/// instantiated from a function template.
484 : public llvm::FoldingSetNode,
485 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
486 MemberSpecializationInfo *> {
487 /// The function template specialization that this structure describes and a
488 /// flag indicating if the function is a member specialization.
489 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
490
491 /// The function template from which this function template
492 /// specialization was generated.
493 ///
494 /// The two bits contain the top 4 values of TemplateSpecializationKind.
495 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
496
497public:
498 /// The template arguments used to produce the function template
499 /// specialization from the function template.
501
502 /// The template arguments as written in the sources, if provided.
503 /// FIXME: Normally null; tail-allocate this.
505
506 /// The point at which this function template specialization was
507 /// first instantiated.
509
510private:
512 FunctionDecl *FD, FunctionTemplateDecl *Template,
513 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
514 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
516 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
517 TemplateArguments(TemplateArgs),
518 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
520 if (MSInfo)
521 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
522 }
523
524 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
525 return Function.getInt();
526 }
527
528public:
530
534 const TemplateArgumentList *TemplateArgs,
535 const TemplateArgumentListInfo *TemplateArgsAsWritten,
537
538 /// Retrieve the declaration of the function template specialization.
539 FunctionDecl *getFunction() const { return Function.getPointer(); }
540
541 /// Retrieve the template from which this function was specialized.
542 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
543
544 /// Determine what kind of template specialization this is.
546 return (TemplateSpecializationKind)(Template.getInt() + 1);
547 }
548
551 }
552
553 /// True if this declaration is an explicit specialization,
554 /// explicit instantiation declaration, or explicit instantiation
555 /// definition.
559 }
560
561 /// Set the template specialization kind.
563 assert(TSK != TSK_Undeclared &&
564 "Cannot encode TSK_Undeclared for a function template specialization");
565 Template.setInt(TSK - 1);
566 }
567
568 /// Retrieve the first point of instantiation of this function
569 /// template specialization.
570 ///
571 /// The point of instantiation may be an invalid source location if this
572 /// function has yet to be instantiated.
575 }
576
577 /// Set the (first) point of instantiation of this function template
578 /// specialization.
581 }
582
583 /// Get the specialization info if this function template specialization is
584 /// also a member specialization:
585 ///
586 /// \code
587 /// template<typename> struct A {
588 /// template<typename> void f();
589 /// template<> void f<int>();
590 /// };
591 /// \endcode
592 ///
593 /// Here, A<int>::f<int> is a function template specialization that is
594 /// an explicit specialization of A<int>::f, but it's also a member
595 /// specialization (an implicit instantiation in this case) of A::f<int>.
596 /// Further:
597 ///
598 /// \code
599 /// template<> template<> void A<int>::f<int>() {}
600 /// \endcode
601 ///
602 /// ... declares a function template specialization that is an explicit
603 /// specialization of A<int>::f, and is also an explicit member
604 /// specialization of A::f<int>.
605 ///
606 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
607 /// need not be the same as that returned by getTemplateSpecializationKind(),
608 /// and represents the relationship between the function and the class-scope
609 /// explicit specialization in the original templated class -- whereas our
610 /// TemplateSpecializationKind represents the relationship between the
611 /// function and the function template, and should always be
612 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
614 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
615 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
616 : nullptr;
617 }
618
619 void Profile(llvm::FoldingSetNodeID &ID) {
620 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
621 }
622
623 static void
624 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
625 const ASTContext &Context) {
626 ID.AddInteger(TemplateArgs.size());
627 for (const TemplateArgument &TemplateArg : TemplateArgs)
628 TemplateArg.Profile(ID, Context);
629 }
630};
631
632/// Provides information a specialization of a member of a class
633/// template, which may be a member function, static data member,
634/// member class or member enumeration.
636 // The member declaration from which this member was instantiated, and the
637 // manner in which the instantiation occurred (in the lower two bits).
638 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
639
640 // The point at which this member was first instantiated.
641 SourceLocation PointOfInstantiation;
642
643public:
644 explicit
647 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
648 assert(TSK != TSK_Undeclared &&
649 "Cannot encode undeclared template specializations for members");
650 }
651
652 /// Retrieve the member declaration from which this member was
653 /// instantiated.
654 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
655
656 /// Determine what kind of template specialization this is.
658 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
659 }
660
663 }
664
665 /// Set the template specialization kind.
667 assert(TSK != TSK_Undeclared &&
668 "Cannot encode undeclared template specializations for members");
669 MemberAndTSK.setInt(TSK - 1);
670 }
671
672 /// Retrieve the first point of instantiation of this member.
673 /// If the point of instantiation is an invalid location, then this member
674 /// has not yet been instantiated.
676 return PointOfInstantiation;
677 }
678
679 /// Set the first point of instantiation.
681 PointOfInstantiation = POI;
682 }
683};
684
685/// Provides information about a dependent function-template
686/// specialization declaration.
687///
688/// This is used for function templates explicit specializations declared
689/// within class templates:
690///
691/// \code
692/// template<typename> struct A {
693/// template<typename> void f();
694/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
695/// };
696/// \endcode
697///
698/// As well as dependent friend declarations naming function template
699/// specializations declared within class templates:
700///
701/// \code
702/// template <class T> void foo(T);
703/// template <class T> class A {
704/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
705/// };
706/// \endcode
708 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
709 FunctionTemplateDecl *> {
710 friend TrailingObjects;
711
712 /// The number of candidates for the primary template.
713 unsigned NumCandidates;
714
716 const UnresolvedSetImpl &Candidates,
717 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
718
719public:
720 /// The template arguments as written in the sources, if provided.
722
724 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
725 const TemplateArgumentListInfo *TemplateArgs);
726
727 /// Returns the candidates for the primary function template.
729 return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
730 }
731};
732
733/// Declaration of a redeclarable template.
735 public Redeclarable<RedeclarableTemplateDecl>
736{
738
739 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
740 return getNextRedeclaration();
741 }
742
743 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
744 return getPreviousDecl();
745 }
746
747 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
748 return getMostRecentDecl();
749 }
750
751 void anchor() override;
752protected:
753 template <typename EntryType> struct SpecEntryTraits {
754 using DeclType = EntryType;
755
756 static DeclType *getDecl(EntryType *D) {
757 return D;
758 }
759
761 return D->getTemplateArgs().asArray();
762 }
763 };
764
765 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
766 typename DeclType = typename SETraits::DeclType>
768 : llvm::iterator_adaptor_base<
769 SpecIterator<EntryType, SETraits, DeclType>,
770 typename llvm::FoldingSetVector<EntryType>::iterator,
771 typename std::iterator_traits<typename llvm::FoldingSetVector<
772 EntryType>::iterator>::iterator_category,
773 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
774 SpecIterator() = default;
775 explicit SpecIterator(
776 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
777 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
778
779 DeclType *operator*() const {
780 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
781 }
782
783 DeclType *operator->() const { return **this; }
784 };
785
786 template <typename EntryType>
787 static SpecIterator<EntryType>
788 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
789 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
790 }
791
792 void loadLazySpecializationsImpl() const;
793
794 template <class EntryType, typename ...ProfileArguments>
796 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
797 void *&InsertPos, ProfileArguments &&...ProfileArgs);
798
799 template <class Derived, class EntryType>
800 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
801 EntryType *Entry, void *InsertPos);
802
803 struct CommonBase {
805
806 /// The template from which this was most
807 /// directly instantiated (or null).
808 ///
809 /// The boolean value indicates whether this template
810 /// was explicitly specialized.
811 llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
813
814 /// If non-null, points to an array of specializations (including
815 /// partial specializations) known only by their external declaration IDs.
816 ///
817 /// The first value in the array is the number of specializations/partial
818 /// specializations that follow.
819 uint32_t *LazySpecializations = nullptr;
820
821 /// The set of "injected" template arguments used within this
822 /// template.
823 ///
824 /// This pointer refers to the template arguments (there are as
825 /// many template arguments as template parameters) for the
826 /// template, and is allocated lazily, since most templates do not
827 /// require the use of this information.
829 };
830
831 /// Pointer to the common data shared by all declarations of this
832 /// template.
833 mutable CommonBase *Common = nullptr;
834
835 /// Retrieves the "common" pointer shared by all (re-)declarations of
836 /// the same template. Calling this routine may implicitly allocate memory
837 /// for the common pointer.
838 CommonBase *getCommonPtr() const;
839
840 virtual CommonBase *newCommon(ASTContext &C) const = 0;
841
842 // Construct a template decl with name, parameters, and templated element.
846 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
847
848public:
849 friend class ASTDeclReader;
850 friend class ASTDeclWriter;
851 friend class ASTReader;
852 template <class decl_type> friend class RedeclarableTemplate;
853
854 /// Retrieves the canonical declaration of this template.
856 return getFirstDecl();
857 }
859 return getFirstDecl();
860 }
861
862 /// Determines whether this template was a specialization of a
863 /// member template.
864 ///
865 /// In the following example, the function template \c X<int>::f and the
866 /// member template \c X<int>::Inner are member specializations.
867 ///
868 /// \code
869 /// template<typename T>
870 /// struct X {
871 /// template<typename U> void f(T, U);
872 /// template<typename U> struct Inner;
873 /// };
874 ///
875 /// template<> template<typename T>
876 /// void X<int>::f(int, T);
877 /// template<> template<typename T>
878 /// struct X<int>::Inner { /* ... */ };
879 /// \endcode
881 return getCommonPtr()->InstantiatedFromMember.getInt();
882 }
883
884 /// Note that this member template is a specialization.
886 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
887 "Only member templates can be member template specializations");
888 getCommonPtr()->InstantiatedFromMember.setInt(true);
889 }
890
891 /// Retrieve the member template from which this template was
892 /// instantiated, or nullptr if this template was not instantiated from a
893 /// member template.
894 ///
895 /// A template is instantiated from a member template when the member
896 /// template itself is part of a class template (or member thereof). For
897 /// example, given
898 ///
899 /// \code
900 /// template<typename T>
901 /// struct X {
902 /// template<typename U> void f(T, U);
903 /// };
904 ///
905 /// void test(X<int> x) {
906 /// x.f(1, 'a');
907 /// };
908 /// \endcode
909 ///
910 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
911 /// template
912 ///
913 /// \code
914 /// template<typename U> void X<int>::f(int, U);
915 /// \endcode
916 ///
917 /// which was itself created during the instantiation of \c X<int>. Calling
918 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
919 /// retrieve the FunctionTemplateDecl for the original template \c f within
920 /// the class template \c X<T>, i.e.,
921 ///
922 /// \code
923 /// template<typename T>
924 /// template<typename U>
925 /// void X<T>::f(T, U);
926 /// \endcode
928 return getCommonPtr()->InstantiatedFromMember.getPointer();
929 }
930
932 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
933 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
934 }
935
936 /// Retrieve the "injected" template arguments that correspond to the
937 /// template parameters of this template.
938 ///
939 /// Although the C++ standard has no notion of the "injected" template
940 /// arguments for a template, the notion is convenient when
941 /// we need to perform substitutions inside the definition of a template.
943
945 using redecl_iterator = redeclarable_base::redecl_iterator;
946
953
954 // Implement isa/cast/dyncast/etc.
955 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
956
957 static bool classofKind(Kind K) {
958 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
959 }
960};
961
962template <> struct RedeclarableTemplateDecl::
963SpecEntryTraits<FunctionTemplateSpecializationInfo> {
965
967 return I->getFunction();
968 }
969
972 return I->TemplateArguments->asArray();
973 }
974};
975
976/// Declaration of a template function.
978protected:
979 friend class FunctionDecl;
980
981 /// Data that is common to all of the declarations of a given
982 /// function template.
984 /// The function template specializations for this function
985 /// template, including explicit specializations and instantiations.
986 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
987
988 Common() = default;
989 };
990
994 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
995 Decl) {}
996
997 CommonBase *newCommon(ASTContext &C) const override;
998
1000 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
1001 }
1002
1003 /// Retrieve the set of function template specializations of this
1004 /// function template.
1005 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
1006 getSpecializations() const;
1007
1008 /// Add a specialization of this function template.
1009 ///
1010 /// \param InsertPos Insert position in the FoldingSetVector, must have been
1011 /// retrieved by an earlier call to findSpecialization().
1013 void *InsertPos);
1014
1015public:
1016 friend class ASTDeclReader;
1017 friend class ASTDeclWriter;
1018
1019 /// Load any lazily-loaded specializations from the external source.
1020 void LoadLazySpecializations() const;
1021
1022 /// Get the underlying function declaration of the template.
1024 return static_cast<FunctionDecl *>(TemplatedDecl);
1025 }
1026
1027 /// Returns whether this template declaration defines the primary
1028 /// pattern.
1031 }
1032
1033 /// Return the specialization with the provided arguments if it exists,
1034 /// otherwise return the insertion point.
1036 void *&InsertPos);
1037
1039 return cast<FunctionTemplateDecl>(
1041 }
1043 return cast<FunctionTemplateDecl>(
1045 }
1046
1047 /// Retrieve the previous declaration of this function template, or
1048 /// nullptr if no such declaration exists.
1050 return cast_or_null<FunctionTemplateDecl>(
1051 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1052 }
1054 return cast_or_null<FunctionTemplateDecl>(
1055 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1056 }
1057
1059 return cast<FunctionTemplateDecl>(
1060 static_cast<RedeclarableTemplateDecl *>(this)
1061 ->getMostRecentDecl());
1062 }
1064 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1065 }
1066
1068 return cast_or_null<FunctionTemplateDecl>(
1070 }
1071
1073 using spec_range = llvm::iterator_range<spec_iterator>;
1074
1076 return spec_range(spec_begin(), spec_end());
1077 }
1078
1080 return makeSpecIterator(getSpecializations(), false);
1081 }
1082
1084 return makeSpecIterator(getSpecializations(), true);
1085 }
1086
1087 /// Return whether this function template is an abbreviated function template,
1088 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1089 bool isAbbreviated() const {
1090 // Since the invented template parameters generated from 'auto' parameters
1091 // are either appended to the end of the explicit template parameter list or
1092 // form a new template parameter list, we can simply observe the last
1093 // parameter to determine if such a thing happened.
1095 return TPL->getParam(TPL->size() - 1)->isImplicit();
1096 }
1097
1098 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1100
1101 /// Create a function template node.
1104 DeclarationName Name,
1105 TemplateParameterList *Params,
1106 NamedDecl *Decl);
1107
1108 /// Create an empty function template node.
1110
1111 // Implement isa/cast/dyncast support
1112 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1113 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1114};
1115
1116//===----------------------------------------------------------------------===//
1117// Kinds of Template Parameters
1118//===----------------------------------------------------------------------===//
1119
1120/// Defines the position of a template parameter within a template
1121/// parameter list.
1122///
1123/// Because template parameter can be listed
1124/// sequentially for out-of-line template members, each template parameter is
1125/// given a Depth - the nesting of template parameter scopes - and a Position -
1126/// the occurrence within the parameter list.
1127/// This class is inheritedly privately by different kinds of template
1128/// parameters and is not part of the Decl hierarchy. Just a facility.
1130protected:
1131 enum { DepthWidth = 20, PositionWidth = 12 };
1132 unsigned Depth : DepthWidth;
1134
1135 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1136 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1137
1138 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1139 // The input may fill maximum values to show that it is invalid.
1140 // Add one here to convert it to zero.
1141 assert((D + 1) <= MaxDepth &&
1142 "The depth of template parmeter position is more than 2^20!");
1143 assert((P + 1) <= MaxPosition &&
1144 "The position of template parmeter position is more than 2^12!");
1145 }
1146
1147public:
1149
1150 /// Get the nesting depth of the template parameter.
1151 unsigned getDepth() const { return Depth; }
1152 void setDepth(unsigned D) {
1153 assert((D + 1) <= MaxDepth &&
1154 "The depth of template parmeter position is more than 2^20!");
1155 Depth = D;
1156 }
1157
1158 /// Get the position of the template parameter within its parameter list.
1159 unsigned getPosition() const { return Position; }
1160 void setPosition(unsigned P) {
1161 assert((P + 1) <= MaxPosition &&
1162 "The position of template parmeter position is more than 2^12!");
1163 Position = P;
1164 }
1165
1166 /// Get the index of the template parameter within its parameter list.
1167 unsigned getIndex() const { return Position; }
1168};
1169
1170/// Declaration of a template type parameter.
1171///
1172/// For example, "T" in
1173/// \code
1174/// template<typename T> class vector;
1175/// \endcode
1176class TemplateTypeParmDecl final : public TypeDecl,
1177 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1178 /// Sema creates these on the stack during auto type deduction.
1179 friend class Sema;
1180 friend TrailingObjects;
1181 friend class ASTDeclReader;
1182
1183 /// Whether this template type parameter was declaration with
1184 /// the 'typename' keyword.
1185 ///
1186 /// If false, it was declared with the 'class' keyword.
1187 bool Typename : 1;
1188
1189 /// Whether this template type parameter has a type-constraint construct.
1190 bool HasTypeConstraint : 1;
1191
1192 /// Whether the type constraint has been initialized. This can be false if the
1193 /// constraint was not initialized yet or if there was an error forming the
1194 /// type constraint.
1195 bool TypeConstraintInitialized : 1;
1196
1197 /// Whether this type template parameter is an "expanded"
1198 /// parameter pack, meaning that its type is a pack expansion and we
1199 /// already know the set of types that expansion expands to.
1200 bool ExpandedParameterPack : 1;
1201
1202 /// The number of type parameters in an expanded parameter pack.
1203 unsigned NumExpanded = 0;
1204
1205 /// The default template argument, if any.
1206 using DefArgStorage =
1208 DefArgStorage DefaultArgument;
1209
1211 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1212 bool HasTypeConstraint,
1213 std::optional<unsigned> NumExpanded)
1214 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1215 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1216 ExpandedParameterPack(NumExpanded),
1217 NumExpanded(NumExpanded.value_or(0)) {}
1218
1219public:
1220 static TemplateTypeParmDecl *
1221 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1222 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1223 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1224 std::optional<unsigned> NumExpanded = std::nullopt);
1226 unsigned ID);
1228 unsigned ID,
1229 bool HasTypeConstraint);
1230
1231 /// Whether this template type parameter was declared with
1232 /// the 'typename' keyword.
1233 ///
1234 /// If not, it was either declared with the 'class' keyword or with a
1235 /// type-constraint (see hasTypeConstraint()).
1237 return Typename && !HasTypeConstraint;
1238 }
1239
1240 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1241
1242 /// Determine whether this template parameter has a default
1243 /// argument.
1244 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1245
1246 /// Retrieve the default argument, if any.
1248 return DefaultArgument.get()->getType();
1249 }
1250
1251 /// Retrieves the default argument's source information, if any.
1253 return DefaultArgument.get();
1254 }
1255
1256 /// Retrieves the location of the default argument declaration.
1258
1259 /// Determines whether the default argument was inherited
1260 /// from a previous declaration of this template.
1262 return DefaultArgument.isInherited();
1263 }
1264
1265 /// Set the default argument for this template parameter.
1267 DefaultArgument.set(DefArg);
1268 }
1269
1270 /// Set that this default argument was inherited from another
1271 /// parameter.
1273 TemplateTypeParmDecl *Prev) {
1274 DefaultArgument.setInherited(C, Prev);
1275 }
1276
1277 /// Removes the default argument of this template parameter.
1279 DefaultArgument.clear();
1280 }
1281
1282 /// Set whether this template type parameter was declared with
1283 /// the 'typename' or 'class' keyword.
1284 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1285
1286 /// Retrieve the depth of the template parameter.
1287 unsigned getDepth() const;
1288
1289 /// Retrieve the index of the template parameter.
1290 unsigned getIndex() const;
1291
1292 /// Returns whether this is a parameter pack.
1293 bool isParameterPack() const;
1294
1295 /// Whether this parameter pack is a pack expansion.
1296 ///
1297 /// A template type template parameter pack can be a pack expansion if its
1298 /// type-constraint contains an unexpanded parameter pack.
1299 bool isPackExpansion() const {
1300 if (!isParameterPack())
1301 return false;
1302 if (const TypeConstraint *TC = getTypeConstraint())
1303 if (TC->hasExplicitTemplateArgs())
1304 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1305 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1306 return true;
1307 return false;
1308 }
1309
1310 /// Whether this parameter is a template type parameter pack that has a known
1311 /// list of different type-constraints at different positions.
1312 ///
1313 /// A parameter pack is an expanded parameter pack when the original
1314 /// parameter pack's type-constraint was itself a pack expansion, and that
1315 /// expansion has already been expanded. For example, given:
1316 ///
1317 /// \code
1318 /// template<typename ...Types>
1319 /// struct X {
1320 /// template<convertible_to<Types> ...Convertibles>
1321 /// struct Y { /* ... */ };
1322 /// };
1323 /// \endcode
1324 ///
1325 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1326 /// its type-constraint. When \c Types is supplied with template arguments by
1327 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1328 /// expanded parameter pack. For example, instantiating
1329 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1330 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1331 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1332
1333 /// Retrieves the number of parameters in an expanded parameter pack.
1334 unsigned getNumExpansionParameters() const {
1335 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1336 return NumExpanded;
1337 }
1338
1339 /// Returns the type constraint associated with this template parameter (if
1340 /// any).
1342 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1343 nullptr;
1344 }
1345
1347 Expr *ImmediatelyDeclaredConstraint);
1348
1349 /// Determine whether this template parameter has a type-constraint.
1350 bool hasTypeConstraint() const {
1351 return HasTypeConstraint;
1352 }
1353
1354 /// \brief Get the associated-constraints of this template parameter.
1355 /// This will either be the immediately-introduced constraint or empty.
1356 ///
1357 /// Use this instead of getTypeConstraint for concepts APIs that
1358 /// accept an ArrayRef of constraint expressions.
1360 if (HasTypeConstraint)
1361 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1362 }
1363
1364 SourceRange getSourceRange() const override LLVM_READONLY;
1365
1366 // Implement isa/cast/dyncast/etc.
1367 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1368 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1369};
1370
1371/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1372/// e.g., "Size" in
1373/// @code
1374/// template<int Size> class array { };
1375/// @endcode
1377 : public DeclaratorDecl,
1378 protected TemplateParmPosition,
1379 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1380 std::pair<QualType, TypeSourceInfo *>,
1381 Expr *> {
1382 friend class ASTDeclReader;
1383 friend TrailingObjects;
1384
1385 /// The default template argument, if any, and whether or not
1386 /// it was inherited.
1388 DefArgStorage DefaultArgument;
1389
1390 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1391 // down here to save memory.
1392
1393 /// Whether this non-type template parameter is a parameter pack.
1394 bool ParameterPack;
1395
1396 /// Whether this non-type template parameter is an "expanded"
1397 /// parameter pack, meaning that its type is a pack expansion and we
1398 /// already know the set of types that expansion expands to.
1399 bool ExpandedParameterPack = false;
1400
1401 /// The number of types in an expanded parameter pack.
1402 unsigned NumExpandedTypes = 0;
1403
1404 size_t numTrailingObjects(
1405 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1406 return NumExpandedTypes;
1407 }
1408
1410 SourceLocation IdLoc, unsigned D, unsigned P,
1412 bool ParameterPack, TypeSourceInfo *TInfo)
1413 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1414 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1415
1416 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1417 SourceLocation IdLoc, unsigned D, unsigned P,
1418 IdentifierInfo *Id, QualType T,
1419 TypeSourceInfo *TInfo,
1420 ArrayRef<QualType> ExpandedTypes,
1421 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1422
1423public:
1424 static NonTypeTemplateParmDecl *
1425 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1426 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1427 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1428
1429 static NonTypeTemplateParmDecl *
1430 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1431 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1432 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1433 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1434
1435 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1436 unsigned ID,
1437 bool HasTypeConstraint);
1438 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1439 unsigned ID,
1440 unsigned NumExpandedTypes,
1441 bool HasTypeConstraint);
1442
1448
1449 SourceRange getSourceRange() const override LLVM_READONLY;
1450
1451 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1452
1453 /// Determine whether this template parameter has a default
1454 /// argument.
1455 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1456
1457 /// Retrieve the default argument, if any.
1458 Expr *getDefaultArgument() const { return DefaultArgument.get(); }
1459
1460 /// Retrieve the location of the default argument, if any.
1462
1463 /// Determines whether the default argument was inherited
1464 /// from a previous declaration of this template.
1466 return DefaultArgument.isInherited();
1467 }
1468
1469 /// Set the default argument for this template parameter, and
1470 /// whether that default argument was inherited from another
1471 /// declaration.
1472 void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
1475 DefaultArgument.setInherited(C, Parm);
1476 }
1477
1478 /// Removes the default argument of this template parameter.
1479 void removeDefaultArgument() { DefaultArgument.clear(); }
1480
1481 /// Whether this parameter is a non-type template parameter pack.
1482 ///
1483 /// If the parameter is a parameter pack, the type may be a
1484 /// \c PackExpansionType. In the following example, the \c Dims parameter
1485 /// is a parameter pack (whose type is 'unsigned').
1486 ///
1487 /// \code
1488 /// template<typename T, unsigned ...Dims> struct multi_array;
1489 /// \endcode
1490 bool isParameterPack() const { return ParameterPack; }
1491
1492 /// Whether this parameter pack is a pack expansion.
1493 ///
1494 /// A non-type template parameter pack is a pack expansion if its type
1495 /// contains an unexpanded parameter pack. In this case, we will have
1496 /// built a PackExpansionType wrapping the type.
1497 bool isPackExpansion() const {
1498 return ParameterPack && getType()->getAs<PackExpansionType>();
1499 }
1500
1501 /// Whether this parameter is a non-type template parameter pack
1502 /// that has a known list of different types at different positions.
1503 ///
1504 /// A parameter pack is an expanded parameter pack when the original
1505 /// parameter pack's type was itself a pack expansion, and that expansion
1506 /// has already been expanded. For example, given:
1507 ///
1508 /// \code
1509 /// template<typename ...Types>
1510 /// struct X {
1511 /// template<Types ...Values>
1512 /// struct Y { /* ... */ };
1513 /// };
1514 /// \endcode
1515 ///
1516 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1517 /// which expands \c Types. When \c Types is supplied with template arguments
1518 /// by instantiating \c X, the instantiation of \c Values becomes an
1519 /// expanded parameter pack. For example, instantiating
1520 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1521 /// pack with expansion types \c int and \c unsigned int.
1522 ///
1523 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1524 /// return the expansion types.
1525 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1526
1527 /// Retrieves the number of expansion types in an expanded parameter
1528 /// pack.
1529 unsigned getNumExpansionTypes() const {
1530 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1531 return NumExpandedTypes;
1532 }
1533
1534 /// Retrieve a particular expansion type within an expanded parameter
1535 /// pack.
1536 QualType getExpansionType(unsigned I) const {
1537 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1538 auto TypesAndInfos =
1539 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1540 return TypesAndInfos[I].first;
1541 }
1542
1543 /// Retrieve a particular expansion type source info within an
1544 /// expanded parameter pack.
1546 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1547 auto TypesAndInfos =
1548 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1549 return TypesAndInfos[I].second;
1550 }
1551
1552 /// Return the constraint introduced by the placeholder type of this non-type
1553 /// template parameter (if any).
1555 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1556 nullptr;
1557 }
1558
1560 *getTrailingObjects<Expr *>() = E;
1561 }
1562
1563 /// Determine whether this non-type template parameter's type has a
1564 /// placeholder with a type-constraint.
1566 auto *AT = getType()->getContainedAutoType();
1567 return AT && AT->isConstrained();
1568 }
1569
1570 /// \brief Get the associated-constraints of this template parameter.
1571 /// This will either be a vector of size 1 containing the immediately-declared
1572 /// constraint introduced by the placeholder type, or an empty vector.
1573 ///
1574 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1575 /// concepts APIs that accept an ArrayRef of constraint expressions.
1578 AC.push_back(E);
1579 }
1580
1581 // Implement isa/cast/dyncast/etc.
1582 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1583 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1584};
1585
1586/// TemplateTemplateParmDecl - Declares a template template parameter,
1587/// e.g., "T" in
1588/// @code
1589/// template <template <typename> class T> class container { };
1590/// @endcode
1591/// A template template parameter is a TemplateDecl because it defines the
1592/// name of a template and the template parameters allowable for substitution.
1594 : public TemplateDecl,
1595 protected TemplateParmPosition,
1596 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1597 TemplateParameterList *> {
1598 /// The default template argument, if any.
1599 using DefArgStorage =
1601 DefArgStorage DefaultArgument;
1602
1603 /// Whether this parameter is a parameter pack.
1604 bool ParameterPack;
1605
1606 /// Whether this template template parameter is an "expanded"
1607 /// parameter pack, meaning that it is a pack expansion and we
1608 /// already know the set of template parameters that expansion expands to.
1609 bool ExpandedParameterPack = false;
1610
1611 /// The number of parameters in an expanded parameter pack.
1612 unsigned NumExpandedParams = 0;
1613
1615 unsigned D, unsigned P, bool ParameterPack,
1617 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1618 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1619
1621 unsigned D, unsigned P,
1624
1625 void anchor() override;
1626
1627public:
1628 friend class ASTDeclReader;
1629 friend class ASTDeclWriter;
1631
1633 SourceLocation L, unsigned D,
1634 unsigned P, bool ParameterPack,
1636 TemplateParameterList *Params);
1638 SourceLocation L, unsigned D,
1639 unsigned P,
1641 TemplateParameterList *Params,
1643
1645 unsigned ID);
1647 unsigned ID,
1648 unsigned NumExpansions);
1649
1655
1656 /// Whether this template template parameter is a template
1657 /// parameter pack.
1658 ///
1659 /// \code
1660 /// template<template <class T> ...MetaFunctions> struct Apply;
1661 /// \endcode
1662 bool isParameterPack() const { return ParameterPack; }
1663
1664 /// Whether this parameter pack is a pack expansion.
1665 ///
1666 /// A template template parameter pack is a pack expansion if its template
1667 /// parameter list contains an unexpanded parameter pack.
1668 bool isPackExpansion() const {
1669 return ParameterPack &&
1671 }
1672
1673 /// Whether this parameter is a template template parameter pack that
1674 /// has a known list of different template parameter lists at different
1675 /// positions.
1676 ///
1677 /// A parameter pack is an expanded parameter pack when the original parameter
1678 /// pack's template parameter list was itself a pack expansion, and that
1679 /// expansion has already been expanded. For exampe, given:
1680 ///
1681 /// \code
1682 /// template<typename...Types> struct Outer {
1683 /// template<template<Types> class...Templates> struct Inner;
1684 /// };
1685 /// \endcode
1686 ///
1687 /// The parameter pack \c Templates is a pack expansion, which expands the
1688 /// pack \c Types. When \c Types is supplied with template arguments by
1689 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1690 /// parameter pack.
1691 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1692
1693 /// Retrieves the number of expansion template parameters in
1694 /// an expanded parameter pack.
1696 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1697 return NumExpandedParams;
1698 }
1699
1700 /// Retrieve a particular expansion type within an expanded parameter
1701 /// pack.
1703 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1704 return getTrailingObjects<TemplateParameterList *>()[I];
1705 }
1706
1707 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1708
1709 /// Determine whether this template parameter has a default
1710 /// argument.
1711 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1712
1713 /// Retrieve the default argument, if any.
1715 static const TemplateArgumentLoc NoneLoc;
1716 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1717 }
1718
1719 /// Retrieve the location of the default argument, if any.
1721
1722 /// Determines whether the default argument was inherited
1723 /// from a previous declaration of this template.
1725 return DefaultArgument.isInherited();
1726 }
1727
1728 /// Set the default argument for this template parameter, and
1729 /// whether that default argument was inherited from another
1730 /// declaration.
1731 void setDefaultArgument(const ASTContext &C,
1732 const TemplateArgumentLoc &DefArg);
1735 DefaultArgument.setInherited(C, Prev);
1736 }
1737
1738 /// Removes the default argument of this template parameter.
1739 void removeDefaultArgument() { DefaultArgument.clear(); }
1740
1741 SourceRange getSourceRange() const override LLVM_READONLY {
1745 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1746 }
1747
1748 // Implement isa/cast/dyncast/etc.
1749 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1750 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1751};
1752
1753/// Represents the builtin template declaration which is used to
1754/// implement __make_integer_seq and other builtin templates. It serves
1755/// no real purpose beyond existing as a place to hold template parameters.
1758
1761
1762 void anchor() override;
1763
1764public:
1765 // Implement isa/cast/dyncast support
1766 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1767 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1768
1770 DeclarationName Name,
1771 BuiltinTemplateKind BTK) {
1772 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1773 }
1774
1775 SourceRange getSourceRange() const override LLVM_READONLY {
1776 return {};
1777 }
1778
1780};
1781
1782/// Represents a class template specialization, which refers to
1783/// a class template with a given set of template arguments.
1784///
1785/// Class template specializations represent both explicit
1786/// specialization of class templates, as in the example below, and
1787/// implicit instantiations of class templates.
1788///
1789/// \code
1790/// template<typename T> class array;
1791///
1792/// template<>
1793/// class array<bool> { }; // class template specialization array<bool>
1794/// \endcode
1796 : public CXXRecordDecl, public llvm::FoldingSetNode {
1797 /// Structure that stores information about a class template
1798 /// specialization that was instantiated from a class template partial
1799 /// specialization.
1800 struct SpecializedPartialSpecialization {
1801 /// The class template partial specialization from which this
1802 /// class template specialization was instantiated.
1803 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1804
1805 /// The template argument list deduced for the class template
1806 /// partial specialization itself.
1807 const TemplateArgumentList *TemplateArgs;
1808 };
1809
1810 /// The template that this specialization specializes
1811 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1812 SpecializedTemplate;
1813
1814 /// Further info for explicit template specialization/instantiation.
1815 struct ExplicitSpecializationInfo {
1816 /// The type-as-written.
1817 TypeSourceInfo *TypeAsWritten = nullptr;
1818
1819 /// The location of the extern keyword.
1820 SourceLocation ExternLoc;
1821
1822 /// The location of the template keyword.
1823 SourceLocation TemplateKeywordLoc;
1824
1825 ExplicitSpecializationInfo() = default;
1826 };
1827
1828 /// Further info for explicit template specialization/instantiation.
1829 /// Does not apply to implicit specializations.
1830 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
1831
1832 /// The template arguments used to describe this specialization.
1833 const TemplateArgumentList *TemplateArgs;
1834
1835 /// The point where this template was instantiated (if any)
1836 SourceLocation PointOfInstantiation;
1837
1838 /// The kind of specialization this declaration refers to.
1839 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1840 unsigned SpecializationKind : 3;
1841
1842protected:
1844 DeclContext *DC, SourceLocation StartLoc,
1845 SourceLocation IdLoc,
1846 ClassTemplateDecl *SpecializedTemplate,
1849
1851
1852public:
1853 friend class ASTDeclReader;
1854 friend class ASTDeclWriter;
1855
1857 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1858 SourceLocation StartLoc, SourceLocation IdLoc,
1859 ClassTemplateDecl *SpecializedTemplate,
1863 CreateDeserialized(ASTContext &C, unsigned ID);
1864
1865 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1866 bool Qualified) const override;
1867
1868 // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1869 // different "most recent" declaration from this function for the same
1870 // declaration, because we don't override getMostRecentDeclImpl(). But
1871 // it's not clear that we should override that, because the most recent
1872 // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1874 return cast<ClassTemplateSpecializationDecl>(
1876 }
1877
1878 /// Retrieve the template that this specialization specializes.
1880
1881 /// Retrieve the template arguments of the class template
1882 /// specialization.
1884 return *TemplateArgs;
1885 }
1886
1888 TemplateArgs = Args;
1889 }
1890
1891 /// Determine the kind of specialization that this
1892 /// declaration represents.
1894 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1895 }
1896
1899 }
1900
1901 /// Is this an explicit specialization at class scope (within the class that
1902 /// owns the primary template)? For example:
1903 ///
1904 /// \code
1905 /// template<typename T> struct Outer {
1906 /// template<typename U> struct Inner;
1907 /// template<> struct Inner; // class-scope explicit specialization
1908 /// };
1909 /// \endcode
1911 return isExplicitSpecialization() &&
1912 isa<CXXRecordDecl>(getLexicalDeclContext());
1913 }
1914
1915 /// True if this declaration is an explicit specialization,
1916 /// explicit instantiation declaration, or explicit instantiation
1917 /// definition.
1921 }
1922
1924 SpecializedTemplate = Specialized;
1925 }
1926
1928 SpecializationKind = TSK;
1929 }
1930
1931 /// Get the point of instantiation (if any), or null if none.
1933 return PointOfInstantiation;
1934 }
1935
1937 assert(Loc.isValid() && "point of instantiation must be valid!");
1938 PointOfInstantiation = Loc;
1939 }
1940
1941 /// If this class template specialization is an instantiation of
1942 /// a template (rather than an explicit specialization), return the
1943 /// class template or class template partial specialization from which it
1944 /// was instantiated.
1945 llvm::PointerUnion<ClassTemplateDecl *,
1949 return llvm::PointerUnion<ClassTemplateDecl *,
1951
1953 }
1954
1955 /// Retrieve the class template or class template partial
1956 /// specialization which was specialized by this.
1957 llvm::PointerUnion<ClassTemplateDecl *,
1960 if (const auto *PartialSpec =
1961 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1962 return PartialSpec->PartialSpecialization;
1963
1964 return SpecializedTemplate.get<ClassTemplateDecl*>();
1965 }
1966
1967 /// Retrieve the set of template arguments that should be used
1968 /// to instantiate members of the class template or class template partial
1969 /// specialization from which this class template specialization was
1970 /// instantiated.
1971 ///
1972 /// \returns For a class template specialization instantiated from the primary
1973 /// template, this function will return the same template arguments as
1974 /// getTemplateArgs(). For a class template specialization instantiated from
1975 /// a class template partial specialization, this function will return the
1976 /// deduced template arguments for the class template partial specialization
1977 /// itself.
1979 if (const auto *PartialSpec =
1980 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1981 return *PartialSpec->TemplateArgs;
1982
1983 return getTemplateArgs();
1984 }
1985
1986 /// Note that this class template specialization is actually an
1987 /// instantiation of the given class template partial specialization whose
1988 /// template arguments have been deduced.
1990 const TemplateArgumentList *TemplateArgs) {
1991 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
1992 "Already set to a class template partial specialization!");
1993 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
1994 PS->PartialSpecialization = PartialSpec;
1995 PS->TemplateArgs = TemplateArgs;
1996 SpecializedTemplate = PS;
1997 }
1998
1999 /// Note that this class template specialization is an instantiation
2000 /// of the given class template.
2002 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
2003 "Previously set to a class template partial specialization!");
2004 SpecializedTemplate = TemplDecl;
2005 }
2006
2007 /// Sets the type of this specialization as it was written by
2008 /// the user. This will be a class template specialization type.
2010 if (!ExplicitInfo)
2011 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2012 ExplicitInfo->TypeAsWritten = T;
2013 }
2014
2015 /// Gets the type of this specialization as it was written by
2016 /// the user, if it was so written.
2018 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2019 }
2020
2021 /// Gets the location of the extern keyword, if present.
2023 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2024 }
2025
2026 /// Sets the location of the extern keyword.
2028 if (!ExplicitInfo)
2029 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2030 ExplicitInfo->ExternLoc = Loc;
2031 }
2032
2033 /// Sets the location of the template keyword.
2035 if (!ExplicitInfo)
2036 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2037 ExplicitInfo->TemplateKeywordLoc = Loc;
2038 }
2039
2040 /// Gets the location of the template keyword, if present.
2042 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2043 }
2044
2045 SourceRange getSourceRange() const override LLVM_READONLY;
2046
2047 void Profile(llvm::FoldingSetNodeID &ID) const {
2048 Profile(ID, TemplateArgs->asArray(), getASTContext());
2049 }
2050
2051 static void
2052 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2053 const ASTContext &Context) {
2054 ID.AddInteger(TemplateArgs.size());
2055 for (const TemplateArgument &TemplateArg : TemplateArgs)
2056 TemplateArg.Profile(ID, Context);
2057 }
2058
2059 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2060
2061 static bool classofKind(Kind K) {
2062 return K >= firstClassTemplateSpecialization &&
2063 K <= lastClassTemplateSpecialization;
2064 }
2065};
2066
2069 /// The list of template parameters
2070 TemplateParameterList* TemplateParams = nullptr;
2071
2072 /// The source info for the template arguments as written.
2073 /// FIXME: redundant with TypeAsWritten?
2074 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2075
2076 /// The class template partial specialization from which this
2077 /// class template partial specialization was instantiated.
2078 ///
2079 /// The boolean value will be true to indicate that this class template
2080 /// partial specialization was specialized at this level.
2081 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2082 InstantiatedFromMember;
2083
2085 DeclContext *DC,
2086 SourceLocation StartLoc,
2087 SourceLocation IdLoc,
2088 TemplateParameterList *Params,
2089 ClassTemplateDecl *SpecializedTemplate,
2091 const ASTTemplateArgumentListInfo *ArgsAsWritten,
2093
2095 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2096 InstantiatedFromMember(nullptr, false) {}
2097
2098 void anchor() override;
2099
2100public:
2101 friend class ASTDeclReader;
2102 friend class ASTDeclWriter;
2103
2105 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2106 SourceLocation StartLoc, SourceLocation IdLoc,
2107 TemplateParameterList *Params,
2108 ClassTemplateDecl *SpecializedTemplate,
2110 const TemplateArgumentListInfo &ArgInfos,
2111 QualType CanonInjectedType,
2113
2115 CreateDeserialized(ASTContext &C, unsigned ID);
2116
2118 return cast<ClassTemplatePartialSpecializationDecl>(
2119 static_cast<ClassTemplateSpecializationDecl *>(
2120 this)->getMostRecentDecl());
2121 }
2122
2123 /// Get the list of template parameters
2125 return TemplateParams;
2126 }
2127
2128 /// \brief All associated constraints of this partial specialization,
2129 /// including the requires clause and any constraints derived from
2130 /// constrained-parameters.
2131 ///
2132 /// The constraints in the resulting list are to be treated as if in a
2133 /// conjunction ("and").
2135 TemplateParams->getAssociatedConstraints(AC);
2136 }
2137
2139 return TemplateParams->hasAssociatedConstraints();
2140 }
2141
2142 /// Get the template arguments as written.
2144 return ArgsAsWritten;
2145 }
2146
2147 /// Retrieve the member class template partial specialization from
2148 /// which this particular class template partial specialization was
2149 /// instantiated.
2150 ///
2151 /// \code
2152 /// template<typename T>
2153 /// struct Outer {
2154 /// template<typename U> struct Inner;
2155 /// template<typename U> struct Inner<U*> { }; // #1
2156 /// };
2157 ///
2158 /// Outer<float>::Inner<int*> ii;
2159 /// \endcode
2160 ///
2161 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2162 /// end up instantiating the partial specialization
2163 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2164 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2165 /// \c Outer<float>::Inner<U*>, this function would return
2166 /// \c Outer<T>::Inner<U*>.
2168 const auto *First =
2169 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2170 return First->InstantiatedFromMember.getPointer();
2171 }
2175 }
2176
2179 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2180 First->InstantiatedFromMember.setPointer(PartialSpec);
2181 }
2182
2183 /// Determines whether this class template partial specialization
2184 /// template was a specialization of a member partial specialization.
2185 ///
2186 /// In the following example, the member template partial specialization
2187 /// \c X<int>::Inner<T*> is a member specialization.
2188 ///
2189 /// \code
2190 /// template<typename T>
2191 /// struct X {
2192 /// template<typename U> struct Inner;
2193 /// template<typename U> struct Inner<U*>;
2194 /// };
2195 ///
2196 /// template<> template<typename T>
2197 /// struct X<int>::Inner<T*> { /* ... */ };
2198 /// \endcode
2200 const auto *First =
2201 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2202 return First->InstantiatedFromMember.getInt();
2203 }
2204
2205 /// Note that this member template is a specialization.
2207 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2208 assert(First->InstantiatedFromMember.getPointer() &&
2209 "Only member templates can be member template specializations");
2210 return First->InstantiatedFromMember.setInt(true);
2211 }
2212
2213 /// Retrieves the injected specialization type for this partial
2214 /// specialization. This is not the same as the type-decl-type for
2215 /// this partial specialization, which is an InjectedClassNameType.
2217 assert(getTypeForDecl() && "partial specialization has no type set!");
2218 return cast<InjectedClassNameType>(getTypeForDecl())
2219 ->getInjectedSpecializationType();
2220 }
2221
2222 void Profile(llvm::FoldingSetNodeID &ID) const {
2224 getASTContext());
2225 }
2226
2227 static void
2228 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2229 TemplateParameterList *TPL, const ASTContext &Context);
2230
2231 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2232
2233 static bool classofKind(Kind K) {
2234 return K == ClassTemplatePartialSpecialization;
2235 }
2236};
2237
2238/// Declaration of a class template.
2240protected:
2241 /// Data that is common to all of the declarations of a given
2242 /// class template.
2244 /// The class template specializations for this class
2245 /// template, including explicit specializations and instantiations.
2246 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2247
2248 /// The class template partial specializations for this class
2249 /// template.
2250 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2252
2253 /// The injected-class-name type for this class template.
2255
2256 Common() = default;
2257 };
2258
2259 /// Retrieve the set of specializations of this class template.
2260 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2261 getSpecializations() const;
2262
2263 /// Retrieve the set of partial specializations of this class
2264 /// template.
2265 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2267
2270 NamedDecl *Decl)
2271 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2272
2273 CommonBase *newCommon(ASTContext &C) const override;
2274
2276 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2277 }
2278
2281 }
2282
2283public:
2284
2285 friend class ASTDeclReader;
2286 friend class ASTDeclWriter;
2288
2289 /// Load any lazily-loaded specializations from the external source.
2290 void LoadLazySpecializations() const;
2291
2292 /// Get the underlying class declarations of the template.
2294 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2295 }
2296
2297 /// Returns whether this template declaration defines the primary
2298 /// class pattern.
2301 }
2302
2303 /// \brief Create a class template node.
2306 DeclarationName Name,
2307 TemplateParameterList *Params,
2308 NamedDecl *Decl);
2309
2310 /// Create an empty class template node.
2312
2313 /// Return the specialization with the provided arguments if it exists,
2314 /// otherwise return the insertion point.
2316 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2317
2318 /// Insert the specified specialization knowing that it is not already
2319 /// in. InsertPos must be obtained from findSpecialization.
2320 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2321
2323 return cast<ClassTemplateDecl>(
2325 }
2327 return cast<ClassTemplateDecl>(
2329 }
2330
2331 /// Retrieve the previous declaration of this class template, or
2332 /// nullptr if no such declaration exists.
2334 return cast_or_null<ClassTemplateDecl>(
2335 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2336 }
2338 return cast_or_null<ClassTemplateDecl>(
2339 static_cast<const RedeclarableTemplateDecl *>(
2340 this)->getPreviousDecl());
2341 }
2342
2344 return cast<ClassTemplateDecl>(
2345 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2346 }
2348 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2349 }
2350
2352 return cast_or_null<ClassTemplateDecl>(
2354 }
2355
2356 /// Return the partial specialization with the provided arguments if it
2357 /// exists, otherwise return the insertion point.
2360 TemplateParameterList *TPL, void *&InsertPos);
2361
2362 /// Insert the specified partial specialization knowing that it is not
2363 /// already in. InsertPos must be obtained from findPartialSpecialization.
2365 void *InsertPos);
2366
2367 /// Retrieve the partial specializations as an ordered list.
2370
2371 /// Find a class template partial specialization with the given
2372 /// type T.
2373 ///
2374 /// \param T a dependent type that names a specialization of this class
2375 /// template.
2376 ///
2377 /// \returns the class template partial specialization that exactly matches
2378 /// the type \p T, or nullptr if no such partial specialization exists.
2380
2381 /// Find a class template partial specialization which was instantiated
2382 /// from the given member partial specialization.
2383 ///
2384 /// \param D a member class template partial specialization.
2385 ///
2386 /// \returns the class template partial specialization which was instantiated
2387 /// from the given member partial specialization, or nullptr if no such
2388 /// partial specialization exists.
2392
2393 /// Retrieve the template specialization type of the
2394 /// injected-class-name for this class template.
2395 ///
2396 /// The injected-class-name for a class template \c X is \c
2397 /// X<template-args>, where \c template-args is formed from the
2398 /// template arguments that correspond to the template parameters of
2399 /// \c X. For example:
2400 ///
2401 /// \code
2402 /// template<typename T, int N>
2403 /// struct array {
2404 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2405 /// };
2406 /// \endcode
2408
2410 using spec_range = llvm::iterator_range<spec_iterator>;
2411
2413 return spec_range(spec_begin(), spec_end());
2414 }
2415
2417 return makeSpecIterator(getSpecializations(), false);
2418 }
2419
2421 return makeSpecIterator(getSpecializations(), true);
2422 }
2423
2424 // Implement isa/cast/dyncast support
2425 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2426 static bool classofKind(Kind K) { return K == ClassTemplate; }
2427};
2428
2429/// Declaration of a friend template.
2430///
2431/// For example:
2432/// \code
2433/// template <typename T> class A {
2434/// friend class MyVector<T>; // not a friend template
2435/// template <typename U> friend class B; // not a friend template
2436/// template <typename U> friend class Foo<T>::Nested; // friend template
2437/// };
2438/// \endcode
2439///
2440/// \note This class is not currently in use. All of the above
2441/// will yield a FriendDecl, not a FriendTemplateDecl.
2442class FriendTemplateDecl : public Decl {
2443 virtual void anchor();
2444
2445public:
2446 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2447
2448private:
2449 // The number of template parameters; always non-zero.
2450 unsigned NumParams = 0;
2451
2452 // The parameter list.
2453 TemplateParameterList **Params = nullptr;
2454
2455 // The declaration that's a friend of this class.
2456 FriendUnion Friend;
2457
2458 // Location of the 'friend' specifier.
2459 SourceLocation FriendLoc;
2460
2462 TemplateParameterList **Params, unsigned NumParams,
2463 FriendUnion Friend, SourceLocation FriendLoc)
2464 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2465 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2466
2467 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2468
2469public:
2470 friend class ASTDeclReader;
2471
2472 static FriendTemplateDecl *
2473 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2475 SourceLocation FriendLoc);
2476
2478
2479 /// If this friend declaration names a templated type (or
2480 /// a dependent member type of a templated type), return that
2481 /// type; otherwise return null.
2483 return Friend.dyn_cast<TypeSourceInfo*>();
2484 }
2485
2486 /// If this friend declaration names a templated function (or
2487 /// a member function of a templated type), return that type;
2488 /// otherwise return null.
2490 return Friend.dyn_cast<NamedDecl*>();
2491 }
2492
2493 /// Retrieves the location of the 'friend' keyword.
2495 return FriendLoc;
2496 }
2497
2499 assert(i <= NumParams);
2500 return Params[i];
2501 }
2502
2503 unsigned getNumTemplateParameters() const {
2504 return NumParams;
2505 }
2506
2507 // Implement isa/cast/dyncast/etc.
2508 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2509 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2510};
2511
2512/// Declaration of an alias template.
2513///
2514/// For example:
2515/// \code
2516/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2517/// \endcode
2519protected:
2521
2524 NamedDecl *Decl)
2525 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2526 Decl) {}
2527
2528 CommonBase *newCommon(ASTContext &C) const override;
2529
2531 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2532 }
2533
2534public:
2535 friend class ASTDeclReader;
2536 friend class ASTDeclWriter;
2537
2538 /// Get the underlying function declaration of the template.
2540 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2541 }
2542
2543
2545 return cast<TypeAliasTemplateDecl>(
2547 }
2549 return cast<TypeAliasTemplateDecl>(
2551 }
2552
2553 /// Retrieve the previous declaration of this function template, or
2554 /// nullptr if no such declaration exists.
2556 return cast_or_null<TypeAliasTemplateDecl>(
2557 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2558 }
2560 return cast_or_null<TypeAliasTemplateDecl>(
2561 static_cast<const RedeclarableTemplateDecl *>(
2562 this)->getPreviousDecl());
2563 }
2564
2566 return cast_or_null<TypeAliasTemplateDecl>(
2568 }
2569
2570 /// Create a function template node.
2573 DeclarationName Name,
2574 TemplateParameterList *Params,
2575 NamedDecl *Decl);
2576
2577 /// Create an empty alias template node.
2579
2580 // Implement isa/cast/dyncast support
2581 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2582 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2583};
2584
2585/// Represents a variable template specialization, which refers to
2586/// a variable template with a given set of template arguments.
2587///
2588/// Variable template specializations represent both explicit
2589/// specializations of variable templates, as in the example below, and
2590/// implicit instantiations of variable templates.
2591///
2592/// \code
2593/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2594///
2595/// template<>
2596/// constexpr float pi<float>; // variable template specialization pi<float>
2597/// \endcode
2599 public llvm::FoldingSetNode {
2600
2601 /// Structure that stores information about a variable template
2602 /// specialization that was instantiated from a variable template partial
2603 /// specialization.
2604 struct SpecializedPartialSpecialization {
2605 /// The variable template partial specialization from which this
2606 /// variable template specialization was instantiated.
2607 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2608
2609 /// The template argument list deduced for the variable template
2610 /// partial specialization itself.
2611 const TemplateArgumentList *TemplateArgs;
2612 };
2613
2614 /// The template that this specialization specializes.
2615 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2616 SpecializedTemplate;
2617
2618 /// Further info for explicit template specialization/instantiation.
2619 struct ExplicitSpecializationInfo {
2620 /// The type-as-written.
2621 TypeSourceInfo *TypeAsWritten = nullptr;
2622
2623 /// The location of the extern keyword.
2624 SourceLocation ExternLoc;
2625
2626 /// The location of the template keyword.
2627 SourceLocation TemplateKeywordLoc;
2628
2629 ExplicitSpecializationInfo() = default;
2630 };
2631
2632 /// Further info for explicit template specialization/instantiation.
2633 /// Does not apply to implicit specializations.
2634 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
2635
2636 /// The template arguments used to describe this specialization.
2637 const TemplateArgumentList *TemplateArgs;
2638 const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
2639
2640 /// The point where this template was instantiated (if any).
2641 SourceLocation PointOfInstantiation;
2642
2643 /// The kind of specialization this declaration refers to.
2644 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2645 unsigned SpecializationKind : 3;
2646
2647 /// Whether this declaration is a complete definition of the
2648 /// variable template specialization. We can't otherwise tell apart
2649 /// an instantiated declaration from an instantiated definition with
2650 /// no initializer.
2651 LLVM_PREFERRED_TYPE(bool)
2652 unsigned IsCompleteDefinition : 1;
2653
2654protected:
2656 SourceLocation StartLoc, SourceLocation IdLoc,
2657 VarTemplateDecl *SpecializedTemplate,
2658 QualType T, TypeSourceInfo *TInfo,
2659 StorageClass S,
2661
2662 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2663
2664public:
2665 friend class ASTDeclReader;
2666 friend class ASTDeclWriter;
2667 friend class VarDecl;
2668
2670 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2671 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2672 TypeSourceInfo *TInfo, StorageClass S,
2675 unsigned ID);
2676
2677 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2678 bool Qualified) const override;
2679
2681 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2682 return cast<VarTemplateSpecializationDecl>(Recent);
2683 }
2684
2685 /// Retrieve the template that this specialization specializes.
2687
2688 /// Retrieve the template arguments of the variable template
2689 /// specialization.
2690 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2691
2692 // TODO: Always set this when creating the new specialization?
2693 void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2695
2697 return TemplateArgsInfo;
2698 }
2699
2700 /// Determine the kind of specialization that this
2701 /// declaration represents.
2703 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2704 }
2705
2708 }
2709
2711 return isExplicitSpecialization() &&
2712 isa<CXXRecordDecl>(getLexicalDeclContext());
2713 }
2714
2715 /// True if this declaration is an explicit specialization,
2716 /// explicit instantiation declaration, or explicit instantiation
2717 /// definition.
2721 }
2722
2724 SpecializationKind = TSK;
2725 }
2726
2727 /// Get the point of instantiation (if any), or null if none.
2729 return PointOfInstantiation;
2730 }
2731
2733 assert(Loc.isValid() && "point of instantiation must be valid!");
2734 PointOfInstantiation = Loc;
2735 }
2736
2737 void setCompleteDefinition() { IsCompleteDefinition = true; }
2738
2739 /// If this variable template specialization is an instantiation of
2740 /// a template (rather than an explicit specialization), return the
2741 /// variable template or variable template partial specialization from which
2742 /// it was instantiated.
2743 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2746 return llvm::PointerUnion<VarTemplateDecl *,
2748
2750 }
2751
2752 /// Retrieve the variable template or variable template partial
2753 /// specialization which was specialized by this.
2754 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2756 if (const auto *PartialSpec =
2757 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2758 return PartialSpec->PartialSpecialization;
2759
2760 return SpecializedTemplate.get<VarTemplateDecl *>();
2761 }
2762
2763 /// Retrieve the set of template arguments that should be used
2764 /// to instantiate the initializer of the variable template or variable
2765 /// template partial specialization from which this variable template
2766 /// specialization was instantiated.
2767 ///
2768 /// \returns For a variable template specialization instantiated from the
2769 /// primary template, this function will return the same template arguments
2770 /// as getTemplateArgs(). For a variable template specialization instantiated
2771 /// from a variable template partial specialization, this function will the
2772 /// return deduced template arguments for the variable template partial
2773 /// specialization itself.
2775 if (const auto *PartialSpec =
2776 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2777 return *PartialSpec->TemplateArgs;
2778
2779 return getTemplateArgs();
2780 }
2781
2782 /// Note that this variable template specialization is actually an
2783 /// instantiation of the given variable template partial specialization whose
2784 /// template arguments have been deduced.
2786 const TemplateArgumentList *TemplateArgs) {
2787 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2788 "Already set to a variable template partial specialization!");
2789 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2790 PS->PartialSpecialization = PartialSpec;
2791 PS->TemplateArgs = TemplateArgs;
2792 SpecializedTemplate = PS;
2793 }
2794
2795 /// Note that this variable template specialization is an instantiation
2796 /// of the given variable template.
2798 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2799 "Previously set to a variable template partial specialization!");
2800 SpecializedTemplate = TemplDecl;
2801 }
2802
2803 /// Sets the type of this specialization as it was written by
2804 /// the user.
2806 if (!ExplicitInfo)
2807 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2808 ExplicitInfo->TypeAsWritten = T;
2809 }
2810
2811 /// Gets the type of this specialization as it was written by
2812 /// the user, if it was so written.
2814 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2815 }
2816
2817 /// Gets the location of the extern keyword, if present.
2819 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2820 }
2821
2822 /// Sets the location of the extern keyword.
2824 if (!ExplicitInfo)
2825 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2826 ExplicitInfo->ExternLoc = Loc;
2827 }
2828
2829 /// Sets the location of the template keyword.
2831 if (!ExplicitInfo)
2832 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2833 ExplicitInfo->TemplateKeywordLoc = Loc;
2834 }
2835
2836 /// Gets the location of the template keyword, if present.
2838 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2839 }
2840
2841 SourceRange getSourceRange() const override LLVM_READONLY;
2842
2843 void Profile(llvm::FoldingSetNodeID &ID) const {
2844 Profile(ID, TemplateArgs->asArray(), getASTContext());
2845 }
2846
2847 static void Profile(llvm::FoldingSetNodeID &ID,
2848 ArrayRef<TemplateArgument> TemplateArgs,
2849 const ASTContext &Context) {
2850 ID.AddInteger(TemplateArgs.size());
2851 for (const TemplateArgument &TemplateArg : TemplateArgs)
2852 TemplateArg.Profile(ID, Context);
2853 }
2854
2855 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2856
2857 static bool classofKind(Kind K) {
2858 return K >= firstVarTemplateSpecialization &&
2859 K <= lastVarTemplateSpecialization;
2860 }
2861};
2862
2865 /// The list of template parameters
2866 TemplateParameterList *TemplateParams = nullptr;
2867
2868 /// The source info for the template arguments as written.
2869 /// FIXME: redundant with TypeAsWritten?
2870 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2871
2872 /// The variable template partial specialization from which this
2873 /// variable template partial specialization was instantiated.
2874 ///
2875 /// The boolean value will be true to indicate that this variable template
2876 /// partial specialization was specialized at this level.
2877 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2878 InstantiatedFromMember;
2879
2881 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2883 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2885 const ASTTemplateArgumentListInfo *ArgInfos);
2886
2888 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2889 Context),
2890 InstantiatedFromMember(nullptr, false) {}
2891
2892 void anchor() override;
2893
2894public:
2895 friend class ASTDeclReader;
2896 friend class ASTDeclWriter;
2897
2899 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2901 VarTemplateDecl *SpecializedTemplate, QualType T,
2903 const TemplateArgumentListInfo &ArgInfos);
2904
2906 unsigned ID);
2907
2909 return cast<VarTemplatePartialSpecializationDecl>(
2910 static_cast<VarTemplateSpecializationDecl *>(
2911 this)->getMostRecentDecl());
2912 }
2913
2914 /// Get the list of template parameters
2916 return TemplateParams;
2917 }
2918
2919 /// Get the template arguments as written.
2921 return ArgsAsWritten;
2922 }
2923
2924 /// \brief All associated constraints of this partial specialization,
2925 /// including the requires clause and any constraints derived from
2926 /// constrained-parameters.
2927 ///
2928 /// The constraints in the resulting list are to be treated as if in a
2929 /// conjunction ("and").
2931 TemplateParams->getAssociatedConstraints(AC);
2932 }
2933
2935 return TemplateParams->hasAssociatedConstraints();
2936 }
2937
2938 /// \brief Retrieve the member variable template partial specialization from
2939 /// which this particular variable template partial specialization was
2940 /// instantiated.
2941 ///
2942 /// \code
2943 /// template<typename T>
2944 /// struct Outer {
2945 /// template<typename U> U Inner;
2946 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2947 /// };
2948 ///
2949 /// template int* Outer<float>::Inner<int*>;
2950 /// \endcode
2951 ///
2952 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2953 /// end up instantiating the partial specialization
2954 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2955 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2956 /// \c Outer<float>::Inner<U*>, this function would return
2957 /// \c Outer<T>::Inner<U*>.
2959 const auto *First =
2960 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2961 return First->InstantiatedFromMember.getPointer();
2962 }
2963
2964 void
2966 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2967 First->InstantiatedFromMember.setPointer(PartialSpec);
2968 }
2969
2970 /// Determines whether this variable template partial specialization
2971 /// was a specialization of a member partial specialization.
2972 ///
2973 /// In the following example, the member template partial specialization
2974 /// \c X<int>::Inner<T*> is a member specialization.
2975 ///
2976 /// \code
2977 /// template<typename T>
2978 /// struct X {
2979 /// template<typename U> U Inner;
2980 /// template<typename U> U* Inner<U*> = (U*)(0);
2981 /// };
2982 ///
2983 /// template<> template<typename T>
2984 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2985 /// \endcode
2987 const auto *First =
2988 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2989 return First->InstantiatedFromMember.getInt();
2990 }
2991
2992 /// Note that this member template is a specialization.
2994 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2995 assert(First->InstantiatedFromMember.getPointer() &&
2996 "Only member templates can be member template specializations");
2997 return First->InstantiatedFromMember.setInt(true);
2998 }
2999
3000 SourceRange getSourceRange() const override LLVM_READONLY;
3001
3002 void Profile(llvm::FoldingSetNodeID &ID) const {
3004 getASTContext());
3005 }
3006
3007 static void
3008 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3009 TemplateParameterList *TPL, const ASTContext &Context);
3010
3011 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3012
3013 static bool classofKind(Kind K) {
3014 return K == VarTemplatePartialSpecialization;
3015 }
3016};
3017
3018/// Declaration of a variable template.
3020protected:
3021 /// Data that is common to all of the declarations of a given
3022 /// variable template.
3024 /// The variable template specializations for this variable
3025 /// template, including explicit specializations and instantiations.
3026 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3027
3028 /// The variable template partial specializations for this variable
3029 /// template.
3030 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3032
3033 Common() = default;
3034 };
3035
3036 /// Retrieve the set of specializations of this variable template.
3037 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3038 getSpecializations() const;
3039
3040 /// Retrieve the set of partial specializations of this class
3041 /// template.
3042 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3044
3047 NamedDecl *Decl)
3048 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3049
3050 CommonBase *newCommon(ASTContext &C) const override;
3051
3053 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3054 }
3055
3056public:
3057 friend class ASTDeclReader;
3058 friend class ASTDeclWriter;
3059
3060 /// Load any lazily-loaded specializations from the external source.
3061 void LoadLazySpecializations() const;
3062
3063 /// Get the underlying variable declarations of the template.
3065 return static_cast<VarDecl *>(TemplatedDecl);
3066 }
3067
3068 /// Returns whether this template declaration defines the primary
3069 /// variable pattern.
3072 }
3073
3075
3076 /// Create a variable template node.
3079 TemplateParameterList *Params,
3080 VarDecl *Decl);
3081
3082 /// Create an empty variable template node.
3083 static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
3084
3085 /// Return the specialization with the provided arguments if it exists,
3086 /// otherwise return the insertion point.
3088 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3089
3090 /// Insert the specified specialization knowing that it is not already
3091 /// in. InsertPos must be obtained from findSpecialization.
3092 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3093
3095 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3096 }
3098 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3099 }
3100
3101 /// Retrieve the previous declaration of this variable template, or
3102 /// nullptr if no such declaration exists.
3104 return cast_or_null<VarTemplateDecl>(
3105 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3106 }
3108 return cast_or_null<VarTemplateDecl>(
3109 static_cast<const RedeclarableTemplateDecl *>(
3110 this)->getPreviousDecl());
3111 }
3112
3114 return cast<VarTemplateDecl>(
3115 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3116 }
3118 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3119 }
3120
3122 return cast_or_null<VarTemplateDecl>(
3124 }
3125
3126 /// Return the partial specialization with the provided arguments if it
3127 /// exists, otherwise return the insertion point.
3130 TemplateParameterList *TPL, void *&InsertPos);
3131
3132 /// Insert the specified partial specialization knowing that it is not
3133 /// already in. InsertPos must be obtained from findPartialSpecialization.
3135 void *InsertPos);
3136
3137 /// Retrieve the partial specializations as an ordered list.
3140
3141 /// Find a variable template partial specialization which was
3142 /// instantiated
3143 /// from the given member partial specialization.
3144 ///
3145 /// \param D a member variable template partial specialization.
3146 ///
3147 /// \returns the variable template partial specialization which was
3148 /// instantiated
3149 /// from the given member partial specialization, or nullptr if no such
3150 /// partial specialization exists.
3153
3155 using spec_range = llvm::iterator_range<spec_iterator>;
3156
3158 return spec_range(spec_begin(), spec_end());
3159 }
3160
3162 return makeSpecIterator(getSpecializations(), false);
3163 }
3164
3166 return makeSpecIterator(getSpecializations(), true);
3167 }
3168
3169 // Implement isa/cast/dyncast support
3170 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3171 static bool classofKind(Kind K) { return K == VarTemplate; }
3172};
3173
3174/// Declaration of a C++20 concept.
3175class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3176protected:
3178
3181 : TemplateDecl(Concept, DC, L, Name, Params),
3183public:
3186 TemplateParameterList *Params,
3188 static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID);
3189
3191 return ConstraintExpr;
3192 }
3193
3194 SourceRange getSourceRange() const override LLVM_READONLY {
3195 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3197 }
3198
3199 bool isTypeConcept() const {
3200 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3201 }
3202
3204 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3205 }
3207 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3208 }
3209
3210 // Implement isa/cast/dyncast/etc.
3211 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3212 static bool classofKind(Kind K) { return K == Concept; }
3213
3214 friend class ASTReader;
3215 friend class ASTDeclReader;
3216 friend class ASTDeclWriter;
3217};
3218
3219// An implementation detail of ConceptSpecialicationExpr that holds the template
3220// arguments, so we can later use this to reconstitute the template arguments
3221// during constraint checking.
3223 : public Decl,
3224 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3225 TemplateArgument> {
3226 unsigned NumTemplateArgs;
3227
3229 ArrayRef<TemplateArgument> ConvertedArgs);
3230 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3231
3232public:
3235 ArrayRef<TemplateArgument> ConvertedArgs);
3237 CreateDeserialized(const ASTContext &C, unsigned ID,
3238 unsigned NumTemplateArgs);
3239
3241 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3242 NumTemplateArgs);
3243 }
3245
3246 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3247 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3248
3250 friend class ASTDeclReader;
3251};
3252
3253/// A template parameter object.
3254///
3255/// Template parameter objects represent values of class type used as template
3256/// arguments. There is one template parameter object for each such distinct
3257/// value used as a template argument across the program.
3258///
3259/// \code
3260/// struct A { int x, y; };
3261/// template<A> struct S;
3262/// S<A{1, 2}> s1;
3263/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3264/// \endcode
3266 public Mergeable<TemplateParamObjectDecl>,
3267 public llvm::FoldingSetNode {
3268private:
3269 /// The value of this template parameter object.
3270 APValue Value;
3271
3273 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3274 T),
3275 Value(V) {}
3276
3277 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3278 const APValue &V);
3279 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3280 unsigned ID);
3281
3282 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3283 /// create these.
3284 friend class ASTContext;
3285 friend class ASTReader;
3286 friend class ASTDeclReader;
3287
3288public:
3289 /// Print this template parameter object in a human-readable format.
3290 void printName(llvm::raw_ostream &OS,
3291 const PrintingPolicy &Policy) const override;
3292
3293 /// Print this object as an equivalent expression.
3294 void printAsExpr(llvm::raw_ostream &OS) const;
3295 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3296
3297 /// Print this object as an initializer suitable for a variable of the
3298 /// object's type.
3299 void printAsInit(llvm::raw_ostream &OS) const;
3300 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3301
3302 const APValue &getValue() const { return Value; }
3303
3304 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3305 const APValue &V) {
3306 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3307 V.Profile(ID);
3308 }
3309 void Profile(llvm::FoldingSetNodeID &ID) {
3310 Profile(ID, getType(), getValue());
3311 }
3312
3314 return getFirstDecl();
3315 }
3317 return getFirstDecl();
3318 }
3319
3320 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3321 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3322};
3323
3325 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3326 return PD;
3327 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3328 return PD;
3329 return P.get<TemplateTemplateParmDecl *>();
3330}
3331
3333 auto *TD = dyn_cast<TemplateDecl>(D);
3334 return TD && (isa<ClassTemplateDecl>(TD) ||
3335 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3336 isa<TypeAliasTemplateDecl>(TD) ||
3337 isa<TemplateTemplateParmDecl>(TD))
3338 ? TD
3339 : nullptr;
3340}
3341
3342/// Check whether the template parameter is a pack expansion, and if so,
3343/// determine the number of parameters produced by that expansion. For instance:
3344///
3345/// \code
3346/// template<typename ...Ts> struct A {
3347/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3348/// };
3349/// \endcode
3350///
3351/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3352/// is not a pack expansion, so returns an empty Optional.
3353inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3354 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3355 if (TTP->isExpandedParameterPack())
3356 return TTP->getNumExpansionParameters();
3357 }
3358
3359 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3360 if (NTTP->isExpandedParameterPack())
3361 return NTTP->getNumExpansionTypes();
3362 }
3363
3364 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3365 if (TTP->isExpandedParameterPack())
3366 return TTP->getNumExpansionTemplateParameters();
3367 }
3368
3369 return std::nullopt;
3370}
3371
3372/// Internal helper used by Subst* nodes to retrieve the parameter list
3373/// for their AssociatedDecl.
3374TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3375
3376} // namespace clang
3377
3378#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:3241
int Id
Definition: ASTDiff.cpp:190
StringRef P
static char ID
Definition: Arena.cpp:183
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:5422
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 C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getMostRecentNonInjectedDecl()
Definition: DeclCXX.h:549
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition: DeclCXX.cpp:1864
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)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:128
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:597
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:88
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:907
Kind getKind() const
Definition: DeclBase.h:447
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:432
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:768
Storage for a default argument.
Definition: DeclTemplate.h:318
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
Definition: DeclTemplate.h:379
bool isSet() const
Determine whether there is a default argument for this parameter.
Definition: DeclTemplate.h:345
ArgType get() const
Get the default argument's value.
Definition: DeclTemplate.h:353
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:373
void clear()
Remove the default argument, even if it was inherited.
Definition: DeclTemplate.h:399
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
Definition: DeclTemplate.h:364
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
Definition: DeclTemplate.h:349
Provides information about a dependent function-template specialization declaration.
Definition: DeclTemplate.h:709
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
Definition: DeclTemplate.h:728
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:721
static DependentFunctionTemplateSpecializationInfo * Create(ASTContext &Context, const UnresolvedSetImpl &Candidates, const TemplateArgumentListInfo *TemplateArgs)
Definition: Decl.cpp:4181
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:221
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Definition: DeclTemplate.h:228
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:1957
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2256
Declaration of a template function.
Definition: DeclTemplate.h:977
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
Definition: DeclTemplate.h:999
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)
Definition: DeclTemplate.h:991
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:486
const TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
Definition: DeclTemplate.h:500
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:562
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
Definition: DeclTemplate.h:624
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
Definition: DeclTemplate.h:542
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
Definition: DeclTemplate.h:613
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:504
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
Definition: DeclTemplate.h:573
void Profile(llvm::FoldingSetNodeID &ID)
Definition: DeclTemplate.h:619
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
Definition: DeclTemplate.h:508
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:539
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:545
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
Definition: DeclTemplate.h:579
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
Definition: DeclTemplate.h:556
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:635
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:666
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:657
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
Definition: DeclTemplate.h:675
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
Definition: DeclTemplate.h:645
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Definition: DeclTemplate.h:680
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
Definition: DeclTemplate.h:654
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:248
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:5991
A (possibly-)qualified type.
Definition: Type.h:736
QualType getCanonicalType() const
Definition: Type.h:6833
void * getAsOpaquePtr() const
Definition: Type.h:783
Declaration of a redeclarable template.
Definition: DeclTemplate.h:736
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
Definition: DeclTemplate.h:788
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:843
redeclarable_base::redecl_iterator redecl_iterator
Definition: DeclTemplate.h:945
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:880
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:858
redeclarable_base::redecl_range redecl_range
Definition: DeclTemplate.h:944
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:833
static bool classof(const Decl *D)
Definition: DeclTemplate.h:955
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
Definition: DeclTemplate.h:927
static bool classofKind(Kind K)
Definition: DeclTemplate.h:957
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:855
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
Definition: DeclTemplate.h:885
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
Definition: DeclTemplate.h:931
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:357
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 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:3631
A convenient class for passing around template argument information.
Definition: TemplateBase.h:601
A template argument list.
Definition: DeclTemplate.h:243
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
Definition: DeclTemplate.h:304
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:292
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:282
OnStackType
Type used to indicate that the template argument list itself is a stack object.
Definition: DeclTemplate.h:263
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:301
TemplateArgumentList(OnStackType, ArrayRef< TemplateArgument > Args)
Construct a new, temporary template argument list on the stack.
Definition: DeclTemplate.h:274
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:286
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:295
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:495
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:413
NamedDecl * TemplatedDecl
Definition: DeclTemplate.h:463
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:464
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
Definition: DeclTemplate.h:472
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:445
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:457
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
Definition: DeclTemplate.h:423
void setTemplateParameters(TemplateParameterList *TParams)
Definition: DeclTemplate.h:467
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:451
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:432
static bool classofKind(Kind K)
Definition: DeclTemplate.h:453
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:134
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:143
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:202
const_iterator begin() const
Definition: DeclTemplate.h:132
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:184
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:107
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
Definition: DeclTemplate.h:171
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:129
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:179
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
Definition: DeclTemplate.h:200
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
Definition: DeclTemplate.h:147
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
Definition: DeclTemplate.h:199
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
Definition: DeclTemplate.h:103
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:138
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:198
ArrayRef< const NamedDecl * > asArray() const
Definition: DeclTemplate.h:139
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
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
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 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:3505
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.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:231
Represents a declaration of a type.
Definition: Decl.h:3341
const Type * getTypeForDecl() const
Definition: Decl.h:3365
A container of type source information.
Definition: Type.h:6752
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6763
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2526
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7558
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:704
QualType getType() const
Definition: Decl.h:715
Represents a variable declaration or definition.
Definition: Decl.h:916
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2253
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:2742
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.
void setInstantiationOf(VarTemplateDecl *TemplDecl)
Note that this variable template specialization is an instantiation of the given variable template.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this variable template specialization is an instantiation of a template (rather than an explicit s...
const ASTTemplateArgumentListInfo * getTemplateArgsInfo() const
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
VarTemplateSpecializationDecl * getMostRecentDecl()
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition: Specifiers.h:207
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition: Decl.cpp:77
NamedDecl * getAsNamedDecl(TemplateParameter P)
StorageClass
Storage classes.
Definition: Specifiers.h:243
void * allocateDefaultArgStorageChain(const ASTContext &C)
TemplateDecl * getAsTypeTemplateDecl(Decl *D)
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:5721
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:302
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
Definition: DeclTemplate.h:65
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:183
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:193
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:186
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
@ Other
Other implicit parameter.
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition: Specifiers.h:214
YAML serialization mapping.
Definition: Dominators.h:30
Definition: Format.h:5226
#define true
Definition: stdbool.h:21
#define false
Definition: stdbool.h:22
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:652
Data that is common to all of the declarations of a given class template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:101
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:983
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:986
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
llvm::PointerIntPair< RedeclarableTemplateDecl *, 1, bool > InstantiatedFromMember
The template from which this was most directly instantiated (or null).
Definition: DeclTemplate.h:812
uint32_t * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:819
TemplateArgument * InjectedArgs
The set of "injected" template arguments used within this template.
Definition: DeclTemplate.h:828