clang 23.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"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/FoldingSet.h"
32#include "llvm/ADT/PointerIntPair.h"
33#include "llvm/ADT/PointerUnion.h"
34#include "llvm/ADT/iterator.h"
35#include "llvm/ADT/iterator_range.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/TrailingObjects.h"
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42#include <iterator>
43#include <optional>
44#include <utility>
45
46namespace clang {
47
51class Expr;
53class IdentifierInfo;
55class TemplateDecl;
58class ConceptDecl;
60class VarTemplateDecl;
62
63/// Stores a template parameter of any kind.
65 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
67
69
70/// Stores a list of template parameters for a TemplateDecl and its
71/// derived classes.
73 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
74 Expr *> {
75 /// The template argument list of the template parameter list.
76 TemplateArgument *InjectedArgs = nullptr;
77
78 /// The location of the 'template' keyword.
79 SourceLocation TemplateLoc;
80
81 /// The locations of the '<' and '>' angle brackets.
82 SourceLocation LAngleLoc, RAngleLoc;
83
84 /// The number of template parameters in this template
85 /// parameter list.
86 unsigned NumParams : 29;
87
88 /// Whether this template parameter list contains an unexpanded parameter
89 /// pack.
90 LLVM_PREFERRED_TYPE(bool)
91 unsigned ContainsUnexpandedParameterPack : 1;
92
93 /// Whether this template parameter list has a requires clause.
94 LLVM_PREFERRED_TYPE(bool)
95 unsigned HasRequiresClause : 1;
96
97 /// Whether any of the template parameters has constrained-parameter
98 /// constraint-expression.
99 LLVM_PREFERRED_TYPE(bool)
100 unsigned HasConstrainedParameters : 1;
101
102protected:
104 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
105 SourceLocation RAngleLoc, Expr *RequiresClause);
106
107 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
108 return NumParams;
109 }
110
111 size_t numTrailingObjects(OverloadToken<Expr *>) const {
112 return HasRequiresClause ? 1 : 0;
113 }
114
115public:
116 template <size_t N, bool HasRequiresClause>
119
121 SourceLocation TemplateLoc,
122 SourceLocation LAngleLoc,
124 SourceLocation RAngleLoc,
125 Expr *RequiresClause);
126
127 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
128
129 /// Iterates through the template parameters in this list.
130 using iterator = NamedDecl **;
131
132 /// Iterates through the template parameters in this list.
133 using const_iterator = NamedDecl * const *;
134
135 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
136 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
137 iterator end() { return begin() + NumParams; }
138 const_iterator end() const { return begin() + NumParams; }
139
140 unsigned size() const { return NumParams; }
141 bool empty() const { return NumParams == 0; }
142
145
146 NamedDecl* getParam(unsigned Idx) {
147 assert(Idx < size() && "Template parameter index out-of-range");
148 return begin()[Idx];
149 }
150 const NamedDecl* getParam(unsigned Idx) const {
151 assert(Idx < size() && "Template parameter index out-of-range");
152 return begin()[Idx];
153 }
154
155 /// Returns the minimum number of arguments needed to form a
156 /// template specialization.
157 ///
158 /// This may be fewer than the number of template parameters, if some of
159 /// the parameters have default arguments or if there is a parameter pack.
160 unsigned getMinRequiredArguments() const;
161
162 /// Get the depth of this template parameter list in the set of
163 /// template parameter lists.
164 ///
165 /// The first template parameter list in a declaration will have depth 0,
166 /// the second template parameter list will have depth 1, etc.
167 unsigned getDepth() const;
168
169 /// Determine whether this template parameter list contains an
170 /// unexpanded parameter pack.
172
173 /// Determine whether this template parameter list contains a parameter pack.
174 bool hasParameterPack() const {
175 for (const NamedDecl *P : asArray())
176 if (P->isParameterPack())
177 return true;
178 return false;
179 }
180
181 /// The constraint-expression of the associated requires-clause.
183 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
184 }
185
186 /// The constraint-expression of the associated requires-clause.
187 const Expr *getRequiresClause() const {
188 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
189 }
190
191 /// \brief All associated constraints derived from this template parameter
192 /// list, including the requires clause and any constraints derived from
193 /// constrained-parameters.
194 ///
195 /// The constraints in the resulting list are to be treated as if in a
196 /// conjunction ("and").
199
201
202 /// Get the template argument list of the template parameter list.
204
205 SourceLocation getTemplateLoc() const { return TemplateLoc; }
206 SourceLocation getLAngleLoc() const { return LAngleLoc; }
207 SourceLocation getRAngleLoc() const { return RAngleLoc; }
208
209 SourceRange getSourceRange() const LLVM_READONLY {
210 return SourceRange(TemplateLoc, RAngleLoc);
211 }
212
213 void print(raw_ostream &Out, const ASTContext &Context,
214 bool OmitTemplateKW = false) const;
215 void print(raw_ostream &Out, const ASTContext &Context,
216 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
217
219 const TemplateParameterList *TPL,
220 unsigned Idx);
221};
222
223/// Stores a list of template parameters and the associated
224/// requires-clause (if any) for a TemplateDecl and its derived classes.
225/// Suitable for creating on the stack.
226template <size_t N, bool HasRequiresClause>
228 : public TemplateParameterList::FixedSizeStorageOwner {
229 typename TemplateParameterList::FixedSizeStorage<
230 NamedDecl *, Expr *>::with_counts<
231 N, HasRequiresClause ? 1u : 0u
232 >::type storage;
233
234public:
236 SourceLocation TemplateLoc,
237 SourceLocation LAngleLoc,
239 SourceLocation RAngleLoc,
240 Expr *RequiresClause)
241 : FixedSizeStorageOwner(
242 (assert(N == Params.size()),
243 assert(HasRequiresClause == (RequiresClause != nullptr)),
244 new (static_cast<void *>(&storage)) TemplateParameterList(C,
245 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
246};
247
248/// A template argument list.
249class TemplateArgumentList final
250 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
251 /// The number of template arguments in this template
252 /// argument list.
253 unsigned NumArguments;
254
255 // Constructs an instance with an internal Argument list, containing
256 // a copy of the Args array. (Called by CreateCopy)
257 TemplateArgumentList(ArrayRef<TemplateArgument> Args);
258
259public:
261
262 TemplateArgumentList(const TemplateArgumentList &) = delete;
263 TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
264
265 /// Create a new template argument list that copies the given set of
266 /// template arguments.
267 static TemplateArgumentList *CreateCopy(ASTContext &Context,
269
270 /// Retrieve the template argument at a given index.
271 const TemplateArgument &get(unsigned Idx) const {
272 assert(Idx < NumArguments && "Invalid template argument index");
273 return data()[Idx];
274 }
275
276 /// Retrieve the template argument at a given index.
277 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
278
279 /// Produce this as an array ref.
281 return getTrailingObjects(size());
282 }
283
284 /// Retrieve the number of template arguments in this
285 /// template argument list.
286 unsigned size() const { return NumArguments; }
287
288 /// Retrieve a pointer to the template argument list.
289 const TemplateArgument *data() const { return getTrailingObjects(); }
290};
291
293
294/// Storage for a default argument. This is conceptually either empty, or an
295/// argument value, or a pointer to a previous declaration that had a default
296/// argument.
297///
298/// However, this is complicated by modules: while we require all the default
299/// arguments for a template to be equivalent, there may be more than one, and
300/// we need to track all the originating parameters to determine if the default
301/// argument is visible.
302template<typename ParmDecl, typename ArgType>
304 /// Storage for both the value *and* another parameter from which we inherit
305 /// the default argument. This is used when multiple default arguments for a
306 /// parameter are merged together from different modules.
307 struct Chain {
308 ParmDecl *PrevDeclWithDefaultArg;
309 ArgType Value;
310 };
311 static_assert(sizeof(Chain) == sizeof(void *) * 2,
312 "non-pointer argument type?");
313
314 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
315
316 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
317 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
318 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
319 Parm = Prev;
320 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
321 "should only be one level of indirection");
322 return Parm;
323 }
324
325public:
326 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
327
328 /// Determine whether there is a default argument for this parameter.
329 bool isSet() const { return !ValueOrInherited.isNull(); }
330
331 /// Determine whether the default argument for this parameter was inherited
332 /// from a previous declaration of the same entity.
333 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
334
335 /// Get the default argument's value. This does not consider whether the
336 /// default argument is visible.
337 ArgType get() const {
338 const DefaultArgStorage *Storage = this;
339 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
340 Storage = &Prev->getDefaultArgStorage();
341 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
342 return C->Value;
343 return cast<ArgType>(Storage->ValueOrInherited);
344 }
345
346 /// Get the parameter from which we inherit the default argument, if any.
347 /// This is the parameter on which the default argument was actually written.
348 const ParmDecl *getInheritedFrom() const {
349 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
350 return D;
351 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
352 return C->PrevDeclWithDefaultArg;
353 return nullptr;
354 }
355
356 /// Set the default argument.
357 void set(ArgType Arg) {
358 assert(!isSet() && "default argument already set");
359 ValueOrInherited = Arg;
360 }
361
362 /// Set that the default argument was inherited from another parameter.
363 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
364 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
365 if (!isSet())
366 ValueOrInherited = InheritedFrom;
367 else if ([[maybe_unused]] auto *D =
368 dyn_cast<ParmDecl *>(ValueOrInherited)) {
369 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
370 ValueOrInherited =
371 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
372 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
373 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
374 InheritedFrom));
375 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
376 } else
377 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
378 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
379 }
380
381 /// Remove the default argument, even if it was inherited.
382 void clear() {
383 ValueOrInherited = ArgType();
384 }
385};
386
387//===----------------------------------------------------------------------===//
388// Kinds of Templates
389//===----------------------------------------------------------------------===//
390
391/// \brief The base class of all kinds of template declarations (e.g.,
392/// class, function, etc.).
393///
394/// The TemplateDecl class stores the list of template parameters and a
395/// reference to the templated scoped declaration: the underlying AST node.
396class TemplateDecl : public NamedDecl {
397 void anchor() override;
398
399protected:
400 // Construct a template decl with name, parameters, and templated element.
403
404 // Construct a template decl with the given name and parameters.
405 // Used when there is no templated element (e.g., for tt-params).
407 TemplateParameterList *Params)
408 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
409
410public:
411 friend class ASTDeclReader;
412 friend class ASTDeclWriter;
413
414 /// Get the list of template parameters
418
419 /// \brief Get the total constraint-expression associated with this template,
420 /// including constraint-expressions derived from the requires-clause,
421 /// trailing requires-clause (for functions and methods) and constrained
422 /// template parameters.
425
426 bool hasAssociatedConstraints() const;
427
428 /// Get the underlying, templated declaration.
430
431 // Should a specialization behave like an alias for another type.
432 bool isTypeAlias() const;
433
434 // Implement isa/cast/dyncast/etc.
435 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
436
437 static bool classofKind(Kind K) {
438 return K >= firstTemplate && K <= lastTemplate;
439 }
440
441 SourceRange getSourceRange() const override LLVM_READONLY {
442 return SourceRange(getTemplateParameters()->getTemplateLoc(),
443 TemplatedDecl->getSourceRange().getEnd());
444 }
445
446protected:
449
450public:
452 TemplateParams = TParams;
453 }
454
455 /// Initialize the underlying templated declaration.
456 void init(NamedDecl *NewTemplatedDecl) {
457 if (TemplatedDecl)
458 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
459 else
460 TemplatedDecl = NewTemplatedDecl;
461 }
462};
463
464/// Provides information about a function template specialization,
465/// which is a FunctionDecl that has been explicitly specialization or
466/// instantiated from a function template.
467class FunctionTemplateSpecializationInfo final
468 : public llvm::FoldingSetNode,
469 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
470 MemberSpecializationInfo *> {
471 /// The function template specialization that this structure describes and a
472 /// flag indicating if the function is a member specialization.
473 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
474
475 /// The function template from which this function template
476 /// specialization was generated.
477 ///
478 /// The two bits contain the top 4 values of TemplateSpecializationKind.
479 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
480
481public:
482 /// The template arguments used to produce the function template
483 /// specialization from the function template.
485
486 /// The template arguments as written in the sources, if provided.
487 /// FIXME: Normally null; tail-allocate this.
489
490 /// The point at which this function template specialization was
491 /// first instantiated.
493
494private:
495 FunctionTemplateSpecializationInfo(
496 FunctionDecl *FD, FunctionTemplateDecl *Template,
498 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
500 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
501 TemplateArguments(TemplateArgs),
502 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
504 if (MSInfo)
505 getTrailingObjects()[0] = MSInfo;
506 }
507
508 size_t numTrailingObjects() const { return Function.getInt(); }
509
510public:
512
513 static FunctionTemplateSpecializationInfo *
516 const TemplateArgumentListInfo *TemplateArgsAsWritten,
518
519 /// Retrieve the declaration of the function template specialization.
520 FunctionDecl *getFunction() const { return Function.getPointer(); }
521
522 /// Retrieve the template from which this function was specialized.
523 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
524
525 /// Determine what kind of template specialization this is.
527 return (TemplateSpecializationKind)(Template.getInt() + 1);
528 }
529
533
534 /// True if this declaration is an explicit specialization,
535 /// explicit instantiation declaration, or explicit instantiation
536 /// definition.
541
542 /// Set the template specialization kind.
544 assert(TSK != TSK_Undeclared &&
545 "Cannot encode TSK_Undeclared for a function template specialization");
546 Template.setInt(TSK - 1);
547 }
548
549 /// Retrieve the first point of instantiation of this function
550 /// template specialization.
551 ///
552 /// The point of instantiation may be an invalid source location if this
553 /// function has yet to be instantiated.
557
558 /// Set the (first) point of instantiation of this function template
559 /// specialization.
563
564 /// Get the specialization info if this function template specialization is
565 /// also a member specialization:
566 ///
567 /// \code
568 /// template<typename> struct A {
569 /// template<typename> void f();
570 /// template<> void f<int>();
571 /// };
572 /// \endcode
573 ///
574 /// Here, A<int>::f<int> is a function template specialization that is
575 /// an explicit specialization of A<int>::f, but it's also a member
576 /// specialization (an implicit instantiation in this case) of A::f<int>.
577 /// Further:
578 ///
579 /// \code
580 /// template<> template<> void A<int>::f<int>() {}
581 /// \endcode
582 ///
583 /// ... declares a function template specialization that is an explicit
584 /// specialization of A<int>::f, and is also an explicit member
585 /// specialization of A::f<int>.
586 ///
587 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
588 /// need not be the same as that returned by getTemplateSpecializationKind(),
589 /// and represents the relationship between the function and the class-scope
590 /// explicit specialization in the original templated class -- whereas our
591 /// TemplateSpecializationKind represents the relationship between the
592 /// function and the function template, and should always be
593 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
595 return numTrailingObjects() ? getTrailingObjects()[0] : nullptr;
596 }
597
598 void Profile(llvm::FoldingSetNodeID &ID) {
599 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
600 }
601
602 static void
603 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
604 const ASTContext &Context) {
605 ID.AddInteger(TemplateArgs.size());
606 for (const TemplateArgument &TemplateArg : TemplateArgs)
607 TemplateArg.Profile(ID, Context);
608 }
609};
610
611/// Provides information a specialization of a member of a class
612/// template, which may be a member function, static data member,
613/// member class or member enumeration.
615 // The member declaration from which this member was instantiated, and the
616 // manner in which the instantiation occurred (in the lower two bits).
617 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
618
619 // The point at which this member was first instantiated.
620 SourceLocation PointOfInstantiation;
621
622public:
623 explicit
626 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
627 assert(TSK != TSK_Undeclared &&
628 "Cannot encode undeclared template specializations for members");
629 }
630
631 /// Retrieve the member declaration from which this member was
632 /// instantiated.
633 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
634
635 /// Determine what kind of template specialization this is.
637 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
638 }
639
643
644 /// Set the template specialization kind.
646 assert(TSK != TSK_Undeclared &&
647 "Cannot encode undeclared template specializations for members");
648 MemberAndTSK.setInt(TSK - 1);
649 }
650
651 /// Retrieve the first point of instantiation of this member.
652 /// If the point of instantiation is an invalid location, then this member
653 /// has not yet been instantiated.
655 return PointOfInstantiation;
656 }
657
658 /// Set the first point of instantiation.
660 PointOfInstantiation = POI;
661 }
662};
663
664/// Provides information about a dependent function-template
665/// specialization declaration.
666///
667/// This is used for function templates explicit specializations declared
668/// within class templates:
669///
670/// \code
671/// template<typename> struct A {
672/// template<typename> void f();
673/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
674/// };
675/// \endcode
676///
677/// As well as dependent friend declarations naming function template
678/// specializations declared within class templates:
679///
680/// \code
681/// template <class T> void foo(T);
682/// template <class T> class A {
683/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
684/// };
685/// \endcode
686class DependentFunctionTemplateSpecializationInfo final
687 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
688 FunctionTemplateDecl *> {
689 friend TrailingObjects;
690
691 /// The number of candidates for the primary template.
692 unsigned NumCandidates;
693
694 DependentFunctionTemplateSpecializationInfo(
695 const UnresolvedSetImpl &Candidates,
696 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
697
698public:
699 /// The template arguments as written in the sources, if provided.
701
702 static DependentFunctionTemplateSpecializationInfo *
703 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
704 const TemplateArgumentListInfo *TemplateArgs);
705
706 /// Returns the candidates for the primary function template.
708 return getTrailingObjects(NumCandidates);
709 }
710};
711
712/// Declaration of a redeclarable template.
714 public Redeclarable<RedeclarableTemplateDecl>
715{
716 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
717
719 return getNextRedeclaration();
720 }
721
723 return getPreviousDecl();
724 }
725
727 return getMostRecentDecl();
728 }
729
730 void anchor() override;
731
732protected:
733 template <typename EntryType> struct SpecEntryTraits {
734 using DeclType = EntryType;
735
736 static DeclType *getDecl(EntryType *D) {
737 return D;
738 }
739
741 return D->getTemplateArgs().asArray();
742 }
743 };
744
745 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
746 typename DeclType = typename SETraits::DeclType>
748 : llvm::iterator_adaptor_base<
749 SpecIterator<EntryType, SETraits, DeclType>,
750 typename llvm::FoldingSetVector<EntryType>::iterator,
751 typename std::iterator_traits<typename llvm::FoldingSetVector<
752 EntryType>::iterator>::iterator_category,
753 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
754 SpecIterator() = default;
755 explicit SpecIterator(
756 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
757 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
758
759 DeclType *operator*() const {
760 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
761 }
762
763 DeclType *operator->() const { return **this; }
764 };
765
766 template <typename EntryType>
767 static SpecIterator<EntryType>
768 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
769 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
770 }
771
772 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
773
775 TemplateParameterList *TPL = nullptr) const;
776
777 template <class EntryType, typename... ProfileArguments>
779 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
780 void *&InsertPos, ProfileArguments... ProfileArgs);
781
782 template <class EntryType, typename... ProfileArguments>
784 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
785 void *&InsertPos, ProfileArguments... ProfileArgs);
786
787 template <class Derived, class EntryType>
788 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
789 EntryType *Entry, void *InsertPos);
790
791 struct CommonBase {
793
794 /// The template from which this was most
795 /// directly instantiated (or null).
796 ///
797 /// The boolean value indicates whether this template
798 /// was explicitly specialized.
799 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
801 };
802
803 /// Pointer to the common data shared by all declarations of this
804 /// template.
805 mutable CommonBase *Common = nullptr;
806
807 /// Retrieves the "common" pointer shared by all (re-)declarations of
808 /// the same template. Calling this routine may implicitly allocate memory
809 /// for the common pointer.
810 CommonBase *getCommonPtr() const;
811
812 virtual CommonBase *newCommon(ASTContext &C) const = 0;
813
814 // Construct a template decl with name, parameters, and templated element.
818 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
819
820public:
821 friend class ASTDeclReader;
822 friend class ASTDeclWriter;
823 friend class ASTReader;
824 template <class decl_type> friend class RedeclarableTemplate;
825
826 /// Retrieves the canonical declaration of this template.
828 return getFirstDecl();
829 }
831 return getFirstDecl();
832 }
833
834 /// Determines whether this template was a specialization of a
835 /// member template.
836 ///
837 /// In the following example, the function template \c X<int>::f and the
838 /// member template \c X<int>::Inner are member specializations.
839 ///
840 /// \code
841 /// template<typename T>
842 /// struct X {
843 /// template<typename U> void f(T, U);
844 /// template<typename U> struct Inner;
845 /// };
846 ///
847 /// template<> template<typename T>
848 /// void X<int>::f(int, T);
849 /// template<> template<typename T>
850 /// struct X<int>::Inner { /* ... */ };
851 /// \endcode
853 return getCommonPtr()->InstantiatedFromMember.getInt();
854 }
855
856 /// Note that this member template is a specialization.
858 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
859 "Only member templates can be member template specializations");
860 getCommonPtr()->InstantiatedFromMember.setInt(true);
861 }
862
863 /// Retrieve the member template from which this template was
864 /// instantiated, or nullptr if this template was not instantiated from a
865 /// member template.
866 ///
867 /// A template is instantiated from a member template when the member
868 /// template itself is part of a class template (or member thereof). For
869 /// example, given
870 ///
871 /// \code
872 /// template<typename T>
873 /// struct X {
874 /// template<typename U> void f(T, U);
875 /// };
876 ///
877 /// void test(X<int> x) {
878 /// x.f(1, 'a');
879 /// };
880 /// \endcode
881 ///
882 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
883 /// template
884 ///
885 /// \code
886 /// template<typename U> void X<int>::f(int, U);
887 /// \endcode
888 ///
889 /// which was itself created during the instantiation of \c X<int>. Calling
890 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
891 /// retrieve the FunctionTemplateDecl for the original template \c f within
892 /// the class template \c X<T>, i.e.,
893 ///
894 /// \code
895 /// template<typename T>
896 /// template<typename U>
897 /// void X<T>::f(T, U);
898 /// \endcode
902
904 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
905 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
906 }
907
908 /// Retrieve the "injected" template arguments that correspond to the
909 /// template parameters of this template.
910 ///
911 /// Although the C++ standard has no notion of the "injected" template
912 /// arguments for a template, the notion is convenient when
913 /// we need to perform substitutions inside the definition of a template.
915 getInjectedTemplateArgs(const ASTContext &Context) const {
917 }
918
920 using redecl_iterator = redeclarable_base::redecl_iterator;
921
928
929 // Implement isa/cast/dyncast/etc.
930 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
931
932 static bool classofKind(Kind K) {
933 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
934 }
935};
936
937template <> struct RedeclarableTemplateDecl::
938SpecEntryTraits<FunctionTemplateSpecializationInfo> {
940
944
949};
950
951/// Declaration of a template function.
953protected:
954 friend class FunctionDecl;
955
956 /// Data that is common to all of the declarations of a given
957 /// function template.
959 /// The function template specializations for this function
960 /// template, including explicit specializations and instantiations.
961 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
962
963 Common() = default;
964 };
965
971
972 CommonBase *newCommon(ASTContext &C) const override;
973
975 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
976 }
977
978 /// Retrieve the set of function template specializations of this
979 /// function template.
980 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
981 getSpecializations() const;
982
983 /// Add a specialization of this function template.
984 ///
985 /// \param InsertPos Insert position in the FoldingSetVector, must have been
986 /// retrieved by an earlier call to findSpecialization().
988 void *InsertPos);
989
990public:
991 friend class ASTDeclReader;
992 friend class ASTDeclWriter;
993
994 /// Load any lazily-loaded specializations from the external source.
995 void LoadLazySpecializations() const;
996
997 /// Get the underlying function declaration of the template.
999 return static_cast<FunctionDecl *>(TemplatedDecl);
1000 }
1001
1002 /// Returns whether this template declaration defines the primary
1003 /// pattern.
1007
1012
1013 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1014 // except this is per declaration, while the redeclarable field is
1015 // per chain. This indicates a template redeclaration which
1016 // is compatible with the definition, in the non-trivial case
1017 // where this is not already a definition.
1018 // This is only really needed for instantiating the definition of friend
1019 // function templates, which can have redeclarations in different template
1020 // contexts.
1021 // The bit is actually stored in the FunctionDecl for space efficiency
1022 // reasons.
1027
1028 /// Return the specialization with the provided arguments if it exists,
1029 /// otherwise return the insertion point.
1031 void *&InsertPos);
1032
1041
1042 /// Retrieve the previous declaration of this function template, or
1043 /// nullptr if no such declaration exists.
1045 return cast_or_null<FunctionTemplateDecl>(
1046 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1047 }
1049 return cast_or_null<FunctionTemplateDecl>(
1050 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1051 }
1052
1059 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1060 }
1061
1063 return cast_or_null<FunctionTemplateDecl>(
1065 }
1066
1068 using spec_range = llvm::iterator_range<spec_iterator>;
1069
1071 return spec_range(spec_begin(), spec_end());
1072 }
1073
1075 return makeSpecIterator(getSpecializations(), false);
1076 }
1077
1079 return makeSpecIterator(getSpecializations(), true);
1080 }
1081
1082 /// Return whether this function template is an abbreviated function template,
1083 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1084 bool isAbbreviated() const {
1085 // Since the invented template parameters generated from 'auto' parameters
1086 // are either appended to the end of the explicit template parameter list or
1087 // form a new template parameter list, we can simply observe the last
1088 // parameter to determine if such a thing happened.
1090 return TPL->getParam(TPL->size() - 1)->isImplicit();
1091 }
1092
1093 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1095
1096 /// Create a function template node.
1099 DeclarationName Name,
1100 TemplateParameterList *Params,
1101 NamedDecl *Decl);
1102
1103 /// Create an empty function template node.
1105 GlobalDeclID ID);
1106
1107 // Implement isa/cast/dyncast support
1108 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1109 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1110};
1111
1112//===----------------------------------------------------------------------===//
1113// Kinds of Template Parameters
1114//===----------------------------------------------------------------------===//
1115
1116/// Defines the position of a template parameter within a template
1117/// parameter list.
1118///
1119/// Because template parameter can be listed
1120/// sequentially for out-of-line template members, each template parameter is
1121/// given a Depth - the nesting of template parameter scopes - and a Position -
1122/// the occurrence within the parameter list.
1123/// This class is inheritedly privately by different kinds of template
1124/// parameters and is not part of the Decl hierarchy. Just a facility.
1126protected:
1127 enum { DepthWidth = 20, PositionWidth = 12 };
1128 unsigned Depth : DepthWidth;
1130
1131 TemplateParmPosition(int D, int P) {
1132 setDepth(D);
1133 setPosition(P);
1134 }
1135
1136public:
1138
1139 /// Get the nesting depth of the template parameter.
1140 unsigned getDepth() const { return Depth; }
1141 void setDepth(int D) {
1142 assert(D >= 0 && "The depth cannot be negative");
1143 assert(D < (1 << DepthWidth) && "The depth is too large");
1144 Depth = D;
1145 }
1146
1147 /// Get the position of the template parameter within its parameter list.
1148 unsigned getPosition() const { return Position; }
1149 void setPosition(int P) {
1150 assert(P >= 0 && "The position cannot be negative");
1151 assert(P < (1 << PositionWidth) && "The position is too large");
1152 Position = P;
1153 }
1154
1155 /// Get the index of the template parameter within its parameter list.
1156 unsigned getIndex() const { return Position; }
1157};
1158
1159/// Declaration of a template type parameter.
1160///
1161/// For example, "T" in
1162/// \code
1163/// template<typename T> class vector;
1164/// \endcode
1165class TemplateTypeParmDecl final : public TypeDecl,
1166 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1167 /// Sema creates these on the stack during auto type deduction.
1168 friend class Sema;
1169 friend TrailingObjects;
1170 friend class ASTDeclReader;
1171
1172 /// Whether this template type parameter was declaration with
1173 /// the 'typename' keyword.
1174 ///
1175 /// If false, it was declared with the 'class' keyword.
1176 bool Typename : 1;
1177
1178 /// Whether this template type parameter has a type-constraint construct.
1179 bool HasTypeConstraint : 1;
1180
1181 /// Whether the type constraint has been initialized. This can be false if the
1182 /// constraint was not initialized yet or if there was an error forming the
1183 /// type constraint.
1184 bool TypeConstraintInitialized : 1;
1185
1186 /// The number of type parameters in an expanded parameter pack, if any.
1187 UnsignedOrNone NumExpanded = std::nullopt;
1188
1189 /// The default template argument, if any.
1190 using DefArgStorage =
1192 DefArgStorage DefaultArgument;
1193
1194 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1195 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1196 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1197 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1198 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1199 NumExpanded(NumExpanded) {}
1200
1201public:
1202 static TemplateTypeParmDecl *
1203 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1204 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1205 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1206 UnsignedOrNone NumExpanded = std::nullopt);
1208 GlobalDeclID ID);
1210 GlobalDeclID ID,
1211 bool HasTypeConstraint);
1212
1213 /// Whether this template type parameter was declared with
1214 /// the 'typename' keyword.
1215 ///
1216 /// If not, it was either declared with the 'class' keyword or with a
1217 /// type-constraint (see hasTypeConstraint()).
1219 return Typename && !HasTypeConstraint;
1220 }
1221
1222 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1223
1224 /// Determine whether this template parameter has a default
1225 /// argument.
1226 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1227
1228 /// Retrieve the default argument, if any.
1230 static const TemplateArgumentLoc NoneLoc;
1231 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1232 }
1233
1234 /// Retrieves the location of the default argument declaration.
1236
1237 /// Determines whether the default argument was inherited
1238 /// from a previous declaration of this template.
1240 return DefaultArgument.isInherited();
1241 }
1242
1243 /// Set the default argument for this template parameter.
1244 void setDefaultArgument(const ASTContext &C,
1245 const TemplateArgumentLoc &DefArg);
1246
1247 /// Set that this default argument was inherited from another
1248 /// parameter.
1250 TemplateTypeParmDecl *Prev) {
1251 DefaultArgument.setInherited(C, Prev);
1252 }
1253
1254 /// Removes the default argument of this template parameter.
1256 DefaultArgument.clear();
1257 }
1258
1259 /// Set whether this template type parameter was declared with
1260 /// the 'typename' or 'class' keyword.
1261 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1262
1263 /// Retrieve the depth of the template parameter.
1264 unsigned getDepth() const;
1265
1266 /// Retrieve the index of the template parameter.
1267 unsigned getIndex() const;
1268
1269 /// Returns whether this is a parameter pack.
1270 bool isParameterPack() const;
1271
1272 /// Whether this parameter pack is a pack expansion.
1273 ///
1274 /// A template type template parameter pack can be a pack expansion if its
1275 /// type-constraint contains an unexpanded parameter pack.
1276 bool isPackExpansion() const {
1277 if (!isParameterPack())
1278 return false;
1279 if (const TypeConstraint *TC = getTypeConstraint())
1280 if (TC->hasExplicitTemplateArgs())
1281 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1282 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1283 return true;
1284 return false;
1285 }
1286
1287 /// Whether this parameter is a template type parameter pack that has a known
1288 /// list of different type-constraints at different positions.
1289 ///
1290 /// A parameter pack is an expanded parameter pack when the original
1291 /// parameter pack's type-constraint was itself a pack expansion, and that
1292 /// expansion has already been expanded. For example, given:
1293 ///
1294 /// \code
1295 /// template<typename ...Types>
1296 /// struct X {
1297 /// template<convertible_to<Types> ...Convertibles>
1298 /// struct Y { /* ... */ };
1299 /// };
1300 /// \endcode
1301 ///
1302 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1303 /// its type-constraint. When \c Types is supplied with template arguments by
1304 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1305 /// expanded parameter pack. For example, instantiating
1306 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1307 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1308 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1309 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1310
1311 /// Returns the type constraint associated with this template parameter (if
1312 /// any).
1314 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1315 }
1316
1318 Expr *ImmediatelyDeclaredConstraint,
1319 UnsignedOrNone ArgPackSubstIndex);
1320
1321 /// Determine whether this template parameter has a type-constraint.
1322 bool hasTypeConstraint() const {
1323 return HasTypeConstraint;
1324 }
1325
1326 /// \brief Get the associated-constraints of this template parameter.
1327 /// This will either be the immediately-introduced constraint or empty.
1328 ///
1329 /// Use this instead of getTypeConstraint for concepts APIs that
1330 /// accept an ArrayRef of constraint expressions.
1333 if (HasTypeConstraint)
1334 AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1335 getTypeConstraint()->getArgPackSubstIndex());
1336 }
1337
1338 SourceRange getSourceRange() const override LLVM_READONLY;
1339
1340 // Implement isa/cast/dyncast/etc.
1341 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1342 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1343};
1344
1345/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1346/// e.g., "Size" in
1347/// @code
1348/// template<int Size> class array { };
1349/// @endcode
1350class NonTypeTemplateParmDecl final
1351 : public DeclaratorDecl,
1352 protected TemplateParmPosition,
1353 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1354 std::pair<QualType, TypeSourceInfo *>,
1355 Expr *> {
1356 friend class ASTDeclReader;
1357 friend TrailingObjects;
1358
1359 /// The default template argument, if any, and whether or not
1360 /// it was inherited.
1361 using DefArgStorage =
1363 DefArgStorage DefaultArgument;
1364
1365 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1366 // down here to save memory.
1367
1368 /// Whether this non-type template parameter is a parameter pack.
1369 bool ParameterPack;
1370
1371 /// Whether this non-type template parameter is an "expanded"
1372 /// parameter pack, meaning that its type is a pack expansion and we
1373 /// already know the set of types that expansion expands to.
1374 bool ExpandedParameterPack = false;
1375
1376 /// The number of types in an expanded parameter pack.
1377 unsigned NumExpandedTypes = 0;
1378
1379 size_t numTrailingObjects(
1380 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1381 return NumExpandedTypes;
1382 }
1383
1385 SourceLocation IdLoc, int D, int P,
1386 const IdentifierInfo *Id, QualType T,
1387 bool ParameterPack, TypeSourceInfo *TInfo)
1388 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1389 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1390
1391 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1392 SourceLocation IdLoc, int D, int P,
1393 const IdentifierInfo *Id, QualType T,
1394 TypeSourceInfo *TInfo,
1395 ArrayRef<QualType> ExpandedTypes,
1396 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1397
1398public:
1399 static NonTypeTemplateParmDecl *
1400 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1401 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1402 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1403
1404 static NonTypeTemplateParmDecl *
1405 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1406 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1407 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1408 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1409
1410 static NonTypeTemplateParmDecl *
1411 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1412 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1413 GlobalDeclID ID,
1414 unsigned NumExpandedTypes,
1415 bool HasTypeConstraint);
1416
1422
1423 SourceRange getSourceRange() const override LLVM_READONLY;
1424
1425 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1426
1427 /// Determine whether this template parameter has a default
1428 /// argument.
1429 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1430
1431 /// Retrieve the default argument, if any.
1433 static const TemplateArgumentLoc NoneLoc;
1434 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1435 }
1436
1437 /// Retrieve the location of the default argument, if any.
1439
1440 /// Determines whether the default argument was inherited
1441 /// from a previous declaration of this template.
1443 return DefaultArgument.isInherited();
1444 }
1445
1446 /// Set the default argument for this template parameter, and
1447 /// whether that default argument was inherited from another
1448 /// declaration.
1449 void setDefaultArgument(const ASTContext &C,
1450 const TemplateArgumentLoc &DefArg);
1452 NonTypeTemplateParmDecl *Parm) {
1453 DefaultArgument.setInherited(C, Parm);
1454 }
1455
1456 /// Removes the default argument of this template parameter.
1457 void removeDefaultArgument() { DefaultArgument.clear(); }
1458
1459 /// Whether this parameter is a non-type template parameter pack.
1460 ///
1461 /// If the parameter is a parameter pack, the type may be a
1462 /// \c PackExpansionType. In the following example, the \c Dims parameter
1463 /// is a parameter pack (whose type is 'unsigned').
1464 ///
1465 /// \code
1466 /// template<typename T, unsigned ...Dims> struct multi_array;
1467 /// \endcode
1468 bool isParameterPack() const { return ParameterPack; }
1469
1470 /// Whether this parameter pack is a pack expansion.
1471 ///
1472 /// A non-type template parameter pack is a pack expansion if its type
1473 /// contains an unexpanded parameter pack. In this case, we will have
1474 /// built a PackExpansionType wrapping the type.
1475 bool isPackExpansion() const {
1476 return ParameterPack && getType()->getAs<PackExpansionType>();
1477 }
1478
1479 /// Whether this parameter is a non-type template parameter pack
1480 /// that has a known list of different types at different positions.
1481 ///
1482 /// A parameter pack is an expanded parameter pack when the original
1483 /// parameter pack's type was itself a pack expansion, and that expansion
1484 /// has already been expanded. For example, given:
1485 ///
1486 /// \code
1487 /// template<typename ...Types>
1488 /// struct X {
1489 /// template<Types ...Values>
1490 /// struct Y { /* ... */ };
1491 /// };
1492 /// \endcode
1493 ///
1494 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1495 /// which expands \c Types. When \c Types is supplied with template arguments
1496 /// by instantiating \c X, the instantiation of \c Values becomes an
1497 /// expanded parameter pack. For example, instantiating
1498 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1499 /// pack with expansion types \c int and \c unsigned int.
1500 ///
1501 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1502 /// return the expansion types.
1503 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1504
1505 /// Retrieves the number of expansion types in an expanded parameter
1506 /// pack.
1507 unsigned getNumExpansionTypes() const {
1508 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1509 return NumExpandedTypes;
1510 }
1511
1512 /// Retrieve a particular expansion type within an expanded parameter
1513 /// pack.
1514 QualType getExpansionType(unsigned I) const {
1515 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1516 auto TypesAndInfos =
1517 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1518 return TypesAndInfos[I].first;
1519 }
1520
1521 /// Retrieve a particular expansion type source info within an
1522 /// expanded parameter pack.
1524 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1525 auto TypesAndInfos =
1526 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1527 return TypesAndInfos[I].second;
1528 }
1529
1530 /// Return the constraint introduced by the placeholder type of this non-type
1531 /// template parameter (if any).
1533 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1534 nullptr;
1535 }
1536
1538 *getTrailingObjects<Expr *>() = E;
1539 }
1540
1541 /// Determine whether this non-type template parameter's type has a
1542 /// placeholder with a type-constraint.
1544 auto *AT = getType()->getContainedAutoType();
1545 return AT && AT->isConstrained();
1546 }
1547
1548 /// \brief Get the associated-constraints of this template parameter.
1549 /// This will either be a vector of size 1 containing the immediately-declared
1550 /// constraint introduced by the placeholder type, or an empty vector.
1551 ///
1552 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1553 /// concepts APIs that accept an ArrayRef of constraint expressions.
1557 AC.emplace_back(E);
1558 }
1559
1560 // Implement isa/cast/dyncast/etc.
1561 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1562 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1563};
1564
1565/// TemplateTemplateParmDecl - Declares a template template parameter,
1566/// e.g., "T" in
1567/// @code
1568/// template <template <typename> class T> class container { };
1569/// @endcode
1570/// A template template parameter is a TemplateDecl because it defines the
1571/// name of a template and the template parameters allowable for substitution.
1572class TemplateTemplateParmDecl final
1573 : public TemplateDecl,
1574 protected TemplateParmPosition,
1575 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1576 TemplateParameterList *> {
1577 /// The default template argument, if any.
1578 using DefArgStorage =
1580 DefArgStorage DefaultArgument;
1581
1582 LLVM_PREFERRED_TYPE(TemplateNameKind)
1583 unsigned ParameterKind : 3;
1584
1585 /// Whether this template template parameter was declaration with
1586 /// the 'typename' keyword.
1587 ///
1588 /// If false, it was declared with the 'class' keyword.
1589 LLVM_PREFERRED_TYPE(bool)
1590 unsigned Typename : 1;
1591
1592 /// Whether this parameter is a parameter pack.
1593 LLVM_PREFERRED_TYPE(bool)
1594 unsigned ParameterPack : 1;
1595
1596 /// Whether this template template parameter is an "expanded"
1597 /// parameter pack, meaning that it is a pack expansion and we
1598 /// already know the set of template parameters that expansion expands to.
1599 LLVM_PREFERRED_TYPE(bool)
1600 unsigned ExpandedParameterPack : 1;
1601
1602 /// The number of parameters in an expanded parameter pack.
1603 unsigned NumExpandedParams = 0;
1604
1605 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1606 bool ParameterPack, IdentifierInfo *Id,
1607 TemplateNameKind ParameterKind, bool Typename,
1608 TemplateParameterList *Params)
1609 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1610 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1611 Typename(Typename), ParameterPack(ParameterPack),
1612 ExpandedParameterPack(false) {}
1613
1614 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1615 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1616 bool Typename, TemplateParameterList *Params,
1618
1619 void anchor() override;
1620
1621public:
1622 friend class ASTDeclReader;
1623 friend class ASTDeclWriter;
1625
1626 static TemplateTemplateParmDecl *
1627 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1628 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1629 bool Typename, TemplateParameterList *Params);
1630
1631 static TemplateTemplateParmDecl *
1632 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1633 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1634 TemplateParameterList *Params,
1636
1637 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1638 GlobalDeclID ID);
1639 static TemplateTemplateParmDecl *
1640 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1641
1647
1648 /// Whether this template template parameter was declared with
1649 /// the 'typename' keyword.
1650 bool wasDeclaredWithTypename() const { return Typename; }
1651
1652 /// Set whether this template template parameter was declared with
1653 /// the 'typename' or 'class' keyword.
1654 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
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()[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);
1734 TemplateTemplateParmDecl *Prev) {
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
1749 return static_cast<TemplateNameKind>(ParameterKind);
1750 }
1751
1757
1758 // Implement isa/cast/dyncast/etc.
1759 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1760 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1761};
1762
1763/// Represents the builtin template declaration which is used to
1764/// implement __make_integer_seq and other builtin templates. It serves
1765/// no real purpose beyond existing as a place to hold template parameters.
1766class BuiltinTemplateDecl : public TemplateDecl {
1768
1769 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1771
1772 void anchor() override;
1773
1774public:
1775 // Implement isa/cast/dyncast support
1776 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1777 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1778
1779 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1780 DeclarationName Name,
1781 BuiltinTemplateKind BTK) {
1782 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1783 }
1784
1785 SourceRange getSourceRange() const override LLVM_READONLY {
1786 return {};
1787 }
1788
1790
1791 bool isPackProducingBuiltinTemplate() const;
1792};
1794
1795/// Provides information about an explicit instantiation of a variable or class
1796/// template.
1798 /// The template arguments as written..
1800
1801 /// The location of the extern keyword.
1803
1804 /// The location of the template keyword.
1806
1808};
1809
1811 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1813
1814/// Represents a class template specialization, which refers to
1815/// a class template with a given set of template arguments.
1816///
1817/// Class template specializations represent both explicit
1818/// specialization of class templates, as in the example below, and
1819/// implicit instantiations of class templates.
1820///
1821/// \code
1822/// template<typename T> class array;
1823///
1824/// template<>
1825/// class array<bool> { }; // class template specialization array<bool>
1826/// \endcode
1828 public llvm::FoldingSetNode {
1829 /// Structure that stores information about a class template
1830 /// specialization that was instantiated from a class template partial
1831 /// specialization.
1832 struct SpecializedPartialSpecialization {
1833 /// The class template partial specialization from which this
1834 /// class template specialization was instantiated.
1835 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1836
1837 /// The template argument list deduced for the class template
1838 /// partial specialization itself.
1839 const TemplateArgumentList *TemplateArgs;
1840 };
1841
1842 /// The template that this specialization specializes
1843 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1844 SpecializedTemplate;
1845
1846 /// Further info for explicit template specialization/instantiation.
1847 /// Does not apply to implicit specializations.
1848 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1849
1850 /// The template arguments used to describe this specialization.
1851 const TemplateArgumentList *TemplateArgs;
1852
1853 /// The point where this template was instantiated (if any)
1854 SourceLocation PointOfInstantiation;
1855
1856 /// The kind of specialization this declaration refers to.
1857 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1858 unsigned SpecializationKind : 3;
1859
1860 /// Indicate that we have matched a parameter pack with a non pack
1861 /// argument, when the opposite match is also allowed.
1862 /// This needs to be cached as deduction is performed during declaration,
1863 /// and we need the information to be preserved so that it is consistent
1864 /// during instantiation.
1865 LLVM_PREFERRED_TYPE(bool)
1866 unsigned StrictPackMatch : 1;
1867
1868protected:
1870 DeclContext *DC, SourceLocation StartLoc,
1871 SourceLocation IdLoc,
1872 ClassTemplateDecl *SpecializedTemplate,
1874 bool StrictPackMatch,
1876
1878
1879public:
1880 friend class ASTDeclReader;
1881 friend class ASTDeclWriter;
1882
1884 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1885 SourceLocation StartLoc, SourceLocation IdLoc,
1886 ClassTemplateDecl *SpecializedTemplate,
1887 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1890 GlobalDeclID ID);
1891
1892 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1893 bool Qualified) const override;
1894
1899
1904
1905 /// Retrieve the template that this specialization specializes.
1907
1908 /// Retrieve the template arguments of the class template
1909 /// specialization.
1911 return *TemplateArgs;
1912 }
1913
1915 TemplateArgs = Args;
1916 }
1917
1918 /// Determine the kind of specialization that this
1919 /// declaration represents.
1921 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1922 }
1923
1927
1928 /// Is this an explicit specialization at class scope (within the class that
1929 /// owns the primary template)? For example:
1930 ///
1931 /// \code
1932 /// template<typename T> struct Outer {
1933 /// template<typename U> struct Inner;
1934 /// template<> struct Inner; // class-scope explicit specialization
1935 /// };
1936 /// \endcode
1941
1942 /// True if this declaration is an explicit specialization,
1943 /// explicit instantiation declaration, or explicit instantiation
1944 /// definition.
1949
1951 SpecializedTemplate = Specialized;
1952 }
1953
1955 SpecializationKind = TSK;
1956 }
1957
1958 bool hasStrictPackMatch() const { return StrictPackMatch; }
1959
1960 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1961
1962 /// Get the point of instantiation (if any), or null if none.
1964 return PointOfInstantiation;
1965 }
1966
1968 assert(Loc.isValid() && "point of instantiation must be valid!");
1969 PointOfInstantiation = Loc;
1970 }
1971
1972 /// If this class template specialization is an instantiation of
1973 /// a template (rather than an explicit specialization), return the
1974 /// class template or class template partial specialization from which it
1975 /// was instantiated.
1976 llvm::PointerUnion<ClassTemplateDecl *,
1980 return llvm::PointerUnion<ClassTemplateDecl *,
1982
1984 }
1985
1986 /// Retrieve the class template or class template partial
1987 /// specialization which was specialized by this.
1988 llvm::PointerUnion<ClassTemplateDecl *,
1991 if (const auto *PartialSpec =
1992 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1993 return PartialSpec->PartialSpecialization;
1994
1995 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1996 }
1997
1998 /// Retrieve the set of template arguments that should be used
1999 /// to instantiate members of the class template or class template partial
2000 /// specialization from which this class template specialization was
2001 /// instantiated.
2002 ///
2003 /// \returns For a class template specialization instantiated from the primary
2004 /// template, this function will return the same template arguments as
2005 /// getTemplateArgs(). For a class template specialization instantiated from
2006 /// a class template partial specialization, this function will return the
2007 /// deduced template arguments for the class template partial specialization
2008 /// itself.
2010 if (const auto *PartialSpec =
2011 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2012 return *PartialSpec->TemplateArgs;
2013
2014 return getTemplateArgs();
2015 }
2016
2017 /// Note that this class template specialization is actually an
2018 /// instantiation of the given class template partial specialization whose
2019 /// template arguments have been deduced.
2021 const TemplateArgumentList *TemplateArgs) {
2022 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2023 "Already set to a class template partial specialization!");
2024 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2025 PS->PartialSpecialization = PartialSpec;
2026 PS->TemplateArgs = TemplateArgs;
2027 SpecializedTemplate = PS;
2028 }
2029
2030 /// Note that this class template specialization is an instantiation
2031 /// of the given class template.
2033 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2034 "Previously set to a class template partial specialization!");
2035 SpecializedTemplate = TemplDecl;
2036 }
2037
2038 /// Retrieve the template argument list as written in the sources,
2039 /// if any.
2041 if (auto *Info =
2042 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2043 return Info->TemplateArgsAsWritten;
2044 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2045 }
2046
2047 /// Set the template argument list as written in the sources.
2048 void
2050 if (auto *Info =
2051 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2052 Info->TemplateArgsAsWritten = ArgsWritten;
2053 else
2054 ExplicitInfo = ArgsWritten;
2055 }
2056
2057 /// Set the template argument list as written in the sources.
2062
2063 /// Gets the location of the extern keyword, if present.
2065 if (auto *Info =
2066 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2067 return Info->ExternKeywordLoc;
2068 return SourceLocation();
2069 }
2070
2071 /// Sets the location of the extern keyword.
2073
2074 /// Gets the location of the template keyword, if present.
2076 if (auto *Info =
2077 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2078 return Info->TemplateKeywordLoc;
2079 return SourceLocation();
2080 }
2081
2082 /// Sets the location of the template keyword.
2084
2085 SourceRange getSourceRange() const override LLVM_READONLY;
2086
2087 void Profile(llvm::FoldingSetNodeID &ID) const {
2088 Profile(ID, TemplateArgs->asArray(), getASTContext());
2089 }
2090
2091 static void
2092 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2093 const ASTContext &Context) {
2094 ID.AddInteger(TemplateArgs.size());
2095 for (const TemplateArgument &TemplateArg : TemplateArgs)
2096 TemplateArg.Profile(ID, Context);
2097 }
2098
2099 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2100
2101 static bool classofKind(Kind K) {
2102 return K >= firstClassTemplateSpecialization &&
2103 K <= lastClassTemplateSpecialization;
2104 }
2105};
2106
2107class ClassTemplatePartialSpecializationDecl
2109 /// The list of template parameters
2110 TemplateParameterList *TemplateParams = nullptr;
2111
2112 /// The class template partial specialization from which this
2113 /// class template partial specialization was instantiated.
2114 ///
2115 /// The boolean value will be true to indicate that this class template
2116 /// partial specialization was specialized at this level.
2117 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2118 InstantiatedFromMember;
2119
2120 mutable CanQualType CanonInjectedTST;
2121
2122 ClassTemplatePartialSpecializationDecl(
2123 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2125 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2126 CanQualType CanonInjectedTST,
2127 ClassTemplatePartialSpecializationDecl *PrevDecl);
2128
2129 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2130 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2131 InstantiatedFromMember(nullptr, false) {}
2132
2133 void anchor() override;
2134
2135public:
2136 friend class ASTDeclReader;
2137 friend class ASTDeclWriter;
2138
2139 static ClassTemplatePartialSpecializationDecl *
2140 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2141 SourceLocation StartLoc, SourceLocation IdLoc,
2142 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2143 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2144 ClassTemplatePartialSpecializationDecl *PrevDecl);
2145
2146 static ClassTemplatePartialSpecializationDecl *
2148
2149 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2151 static_cast<ClassTemplateSpecializationDecl *>(
2152 this)->getMostRecentDecl());
2153 }
2154
2155 /// Get the list of template parameters
2157 return TemplateParams;
2158 }
2159
2160 /// \brief All associated constraints of this partial specialization,
2161 /// including the requires clause and any constraints derived from
2162 /// constrained-parameters.
2163 ///
2164 /// The constraints in the resulting list are to be treated as if in a
2165 /// conjunction ("and").
2168 TemplateParams->getAssociatedConstraints(AC);
2169 }
2170
2172 return TemplateParams->hasAssociatedConstraints();
2173 }
2174
2175 /// Retrieve the member class template partial specialization from
2176 /// which this particular class template partial specialization was
2177 /// instantiated.
2178 ///
2179 /// \code
2180 /// template<typename T>
2181 /// struct Outer {
2182 /// template<typename U> struct Inner;
2183 /// template<typename U> struct Inner<U*> { }; // #1
2184 /// };
2185 ///
2186 /// Outer<float>::Inner<int*> ii;
2187 /// \endcode
2188 ///
2189 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2190 /// end up instantiating the partial specialization
2191 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2192 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2193 /// \c Outer<float>::Inner<U*>, this function would return
2194 /// \c Outer<T>::Inner<U*>.
2195 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2196 const auto *First =
2198 return First->InstantiatedFromMember.getPointer();
2199 }
2204
2206 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2208 First->InstantiatedFromMember.setPointer(PartialSpec);
2209 }
2210
2211 /// Determines whether this class template partial specialization
2212 /// template was a specialization of a member partial specialization.
2213 ///
2214 /// In the following example, the member template partial specialization
2215 /// \c X<int>::Inner<T*> is a member specialization.
2216 ///
2217 /// \code
2218 /// template<typename T>
2219 /// struct X {
2220 /// template<typename U> struct Inner;
2221 /// template<typename U> struct Inner<U*>;
2222 /// };
2223 ///
2224 /// template<> template<typename T>
2225 /// struct X<int>::Inner<T*> { /* ... */ };
2226 /// \endcode
2228 const auto *First =
2230 return First->InstantiatedFromMember.getInt();
2231 }
2232
2233 /// Note that this member template is a specialization.
2236 assert(First->InstantiatedFromMember.getPointer() &&
2237 "Only member templates can be member template specializations");
2238 return First->InstantiatedFromMember.setInt(true);
2239 }
2240
2241 /// Retrieves the canonical injected specialization type for this partial
2242 /// specialization.
2245
2246 SourceRange getSourceRange() const override LLVM_READONLY;
2247
2248 void Profile(llvm::FoldingSetNodeID &ID) const {
2250 getASTContext());
2251 }
2252
2253 static void
2254 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2255 TemplateParameterList *TPL, const ASTContext &Context);
2256
2257 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2258
2259 static bool classofKind(Kind K) {
2260 return K == ClassTemplatePartialSpecialization;
2261 }
2262};
2263
2264/// Declaration of a class template.
2266protected:
2267 /// Data that is common to all of the declarations of a given
2268 /// class template.
2270 /// The class template specializations for this class
2271 /// template, including explicit specializations and instantiations.
2272 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2273
2274 /// The class template partial specializations for this class
2275 /// template.
2276 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2278
2279 /// The Injected Template Specialization Type for this declaration.
2281
2282 Common() = default;
2283 };
2284
2285 /// Retrieve the set of specializations of this class template.
2286 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2287 getSpecializations() const;
2288
2289 /// Retrieve the set of partial specializations of this class
2290 /// template.
2291 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2293
2296 NamedDecl *Decl)
2297 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2298
2299 CommonBase *newCommon(ASTContext &C) const override;
2300
2302 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2303 }
2304
2306
2307public:
2308
2309 friend class ASTDeclReader;
2310 friend class ASTDeclWriter;
2312
2313 /// Load any lazily-loaded specializations from the external source.
2314 void LoadLazySpecializations(bool OnlyPartial = false) const;
2315
2316 /// Get the underlying class declarations of the template.
2318 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2319 }
2320
2321 /// Returns whether this template declaration defines the primary
2322 /// class pattern.
2326
2327 /// \brief Create a class template node.
2330 DeclarationName Name,
2331 TemplateParameterList *Params,
2332 NamedDecl *Decl);
2333
2334 /// Create an empty class template node.
2336
2337 /// Return the specialization with the provided arguments if it exists,
2338 /// otherwise return the insertion point.
2340 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2341
2342 /// Insert the specified specialization knowing that it is not already
2343 /// in. InsertPos must be obtained from findSpecialization.
2344 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2345
2354
2355 /// Retrieve the previous declaration of this class template, or
2356 /// nullptr if no such declaration exists.
2358 return cast_or_null<ClassTemplateDecl>(
2359 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2360 }
2362 return cast_or_null<ClassTemplateDecl>(
2363 static_cast<const RedeclarableTemplateDecl *>(
2364 this)->getPreviousDecl());
2365 }
2366
2372 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2373 }
2374
2376 return cast_or_null<ClassTemplateDecl>(
2378 }
2379
2380 /// Return the partial specialization with the provided arguments if it
2381 /// exists, otherwise return the insertion point.
2384 TemplateParameterList *TPL, void *&InsertPos);
2385
2386 /// Insert the specified partial specialization knowing that it is not
2387 /// already in. InsertPos must be obtained from findPartialSpecialization.
2389 void *InsertPos);
2390
2391 /// Retrieve the partial specializations as an ordered list.
2394
2395 /// Find a class template partial specialization with the given
2396 /// type T.
2397 ///
2398 /// \param T a dependent type that names a specialization of this class
2399 /// template.
2400 ///
2401 /// \returns the class template partial specialization that exactly matches
2402 /// the type \p T, or nullptr if no such partial specialization exists.
2404
2405 /// Find a class template partial specialization which was instantiated
2406 /// from the given member partial specialization.
2407 ///
2408 /// \param D a member class template partial specialization.
2409 ///
2410 /// \returns the class template partial specialization which was instantiated
2411 /// from the given member partial specialization, or nullptr if no such
2412 /// partial specialization exists.
2416
2417 /// Retrieve the canonical template specialization type of the
2418 /// injected-class-name for this class template.
2419 ///
2420 /// The injected-class-name for a class template \c X is \c
2421 /// X<template-args>, where \c template-args is formed from the
2422 /// template arguments that correspond to the template parameters of
2423 /// \c X. For example:
2424 ///
2425 /// \code
2426 /// template<typename T, int N>
2427 /// struct array {
2428 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2429 /// };
2430 /// \endcode
2433
2435 using spec_range = llvm::iterator_range<spec_iterator>;
2436
2438 return spec_range(spec_begin(), spec_end());
2439 }
2440
2442 return makeSpecIterator(getSpecializations(), false);
2443 }
2444
2446 return makeSpecIterator(getSpecializations(), true);
2447 }
2448
2449 // Implement isa/cast/dyncast support
2450 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2451 static bool classofKind(Kind K) { return K == ClassTemplate; }
2452};
2453
2454/// Declaration of a friend template.
2455///
2456/// For example:
2457/// \code
2458/// template <typename T> class A {
2459/// friend class MyVector<T>; // not a friend template
2460/// template <typename U> friend class B; // not a friend template
2461/// template <typename U> friend class Foo<T>::Nested; // friend template
2462/// };
2463/// \endcode
2464///
2465/// \note This class is not currently in use. All of the above
2466/// will yield a FriendDecl, not a FriendTemplateDecl.
2467class FriendTemplateDecl : public Decl {
2468 virtual void anchor();
2469
2470public:
2471 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2472
2473private:
2474 // The number of template parameters; always non-zero.
2475 unsigned NumParams = 0;
2476
2477 // The parameter list.
2478 TemplateParameterList **Params = nullptr;
2479
2480 // The declaration that's a friend of this class.
2481 FriendUnion Friend;
2482
2483 // Location of the 'friend' specifier.
2484 SourceLocation FriendLoc;
2485
2486 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2487 TemplateParameterList **Params, unsigned NumParams,
2488 FriendUnion Friend, SourceLocation FriendLoc)
2489 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2490 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2491
2492 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2493
2494public:
2495 friend class ASTDeclReader;
2496
2497 static FriendTemplateDecl *
2498 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2500 SourceLocation FriendLoc);
2501
2502 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2503
2504 /// If this friend declaration names a templated type (or
2505 /// a dependent member type of a templated type), return that
2506 /// type; otherwise return null.
2508 return Friend.dyn_cast<TypeSourceInfo*>();
2509 }
2510
2511 /// If this friend declaration names a templated function (or
2512 /// a member function of a templated type), return that type;
2513 /// otherwise return null.
2515 return Friend.dyn_cast<NamedDecl*>();
2516 }
2517
2518 /// Retrieves the location of the 'friend' keyword.
2520 return FriendLoc;
2521 }
2522
2524 assert(i <= NumParams);
2525 return Params[i];
2526 }
2527
2528 unsigned getNumTemplateParameters() const {
2529 return NumParams;
2530 }
2531
2532 // Implement isa/cast/dyncast/etc.
2533 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2534 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2535};
2536
2537/// Declaration of an alias template.
2538///
2539/// For example:
2540/// \code
2541/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2542/// \endcode
2544protected:
2546
2552
2553 CommonBase *newCommon(ASTContext &C) const override;
2554
2556 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2557 }
2558
2559public:
2560 friend class ASTDeclReader;
2561 friend class ASTDeclWriter;
2562
2563 /// Get the underlying function declaration of the template.
2565 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2566 }
2567
2568
2577
2578 /// Retrieve the previous declaration of this function template, or
2579 /// nullptr if no such declaration exists.
2581 return cast_or_null<TypeAliasTemplateDecl>(
2582 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2583 }
2585 return cast_or_null<TypeAliasTemplateDecl>(
2586 static_cast<const RedeclarableTemplateDecl *>(
2587 this)->getPreviousDecl());
2588 }
2589
2591 return cast_or_null<TypeAliasTemplateDecl>(
2593 }
2594
2595 /// Create a function template node.
2598 DeclarationName Name,
2599 TemplateParameterList *Params,
2600 NamedDecl *Decl);
2601
2602 /// Create an empty alias template node.
2604 GlobalDeclID ID);
2605
2606 // Implement isa/cast/dyncast support
2607 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2608 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2609};
2610
2611/// Represents a variable template specialization, which refers to
2612/// a variable template with a given set of template arguments.
2613///
2614/// Variable template specializations represent both explicit
2615/// specializations of variable templates, as in the example below, and
2616/// implicit instantiations of variable templates.
2617///
2618/// \code
2619/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2620///
2621/// template<>
2622/// constexpr float pi<float>; // variable template specialization pi<float>
2623/// \endcode
2625 public llvm::FoldingSetNode {
2626
2627 /// Structure that stores information about a variable template
2628 /// specialization that was instantiated from a variable template partial
2629 /// specialization.
2630 struct SpecializedPartialSpecialization {
2631 /// The variable template partial specialization from which this
2632 /// variable template specialization was instantiated.
2633 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2634
2635 /// The template argument list deduced for the variable template
2636 /// partial specialization itself.
2637 const TemplateArgumentList *TemplateArgs;
2638 };
2639
2640 /// The template that this specialization specializes.
2641 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2642 SpecializedTemplate;
2643
2644 /// Further info for explicit template specialization/instantiation.
2645 /// Does not apply to implicit specializations.
2646 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2647
2648 /// The template arguments used to describe this specialization.
2649 const TemplateArgumentList *TemplateArgs;
2650
2651 /// The point where this template was instantiated (if any).
2652 SourceLocation PointOfInstantiation;
2653
2654 /// The kind of specialization this declaration refers to.
2655 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2656 unsigned SpecializationKind : 3;
2657
2658 /// Whether this declaration is a complete definition of the
2659 /// variable template specialization. We can't otherwise tell apart
2660 /// an instantiated declaration from an instantiated definition with
2661 /// no initializer.
2662 LLVM_PREFERRED_TYPE(bool)
2663 unsigned IsCompleteDefinition : 1;
2664
2665protected:
2667 SourceLocation StartLoc, SourceLocation IdLoc,
2668 VarTemplateDecl *SpecializedTemplate,
2669 QualType T, TypeSourceInfo *TInfo,
2670 StorageClass S,
2672
2673 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2674
2675public:
2676 friend class ASTDeclReader;
2677 friend class ASTDeclWriter;
2678 friend class VarDecl;
2679
2681 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2682 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2683 TypeSourceInfo *TInfo, StorageClass S,
2686 GlobalDeclID ID);
2687
2688 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2689 bool Qualified) const override;
2690
2692 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2694 }
2695
2696 /// Retrieve the template that this specialization specializes.
2698
2699 /// Retrieve the template arguments of the variable template
2700 /// specialization.
2701 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2702
2703 /// Determine the kind of specialization that this
2704 /// declaration represents.
2706 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2707 }
2708
2712
2717
2718 /// True if this declaration is an explicit specialization,
2719 /// explicit instantiation declaration, or explicit instantiation
2720 /// definition.
2725
2727 SpecializationKind = TSK;
2728 }
2729
2730 /// Get the point of instantiation (if any), or null if none.
2732 return PointOfInstantiation;
2733 }
2734
2736 assert(Loc.isValid() && "point of instantiation must be valid!");
2737 PointOfInstantiation = Loc;
2738 }
2739
2740 void setCompleteDefinition() { IsCompleteDefinition = true; }
2741
2742 /// If this variable template specialization is an instantiation of
2743 /// a template (rather than an explicit specialization), return the
2744 /// variable template or variable template partial specialization from which
2745 /// it was instantiated.
2746 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2749 return llvm::PointerUnion<VarTemplateDecl *,
2751
2753 }
2754
2755 /// Retrieve the variable template or variable template partial
2756 /// specialization which was specialized by this.
2757 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2759 if (const auto *PartialSpec =
2760 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2761 return PartialSpec->PartialSpecialization;
2762
2763 return cast<VarTemplateDecl *>(SpecializedTemplate);
2764 }
2765
2766 /// Retrieve the set of template arguments that should be used
2767 /// to instantiate the initializer of the variable template or variable
2768 /// template partial specialization from which this variable template
2769 /// specialization was instantiated.
2770 ///
2771 /// \returns For a variable template specialization instantiated from the
2772 /// primary template, this function will return the same template arguments
2773 /// as getTemplateArgs(). For a variable template specialization instantiated
2774 /// from a variable template partial specialization, this function will the
2775 /// return deduced template arguments for the variable template partial
2776 /// specialization itself.
2778 if (const auto *PartialSpec =
2779 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2780 return *PartialSpec->TemplateArgs;
2781
2782 return getTemplateArgs();
2783 }
2784
2785 /// Note that this variable template specialization is actually an
2786 /// instantiation of the given variable template partial specialization whose
2787 /// template arguments have been deduced.
2789 const TemplateArgumentList *TemplateArgs) {
2790 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2791 "Already set to a variable template partial specialization!");
2792 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2793 PS->PartialSpecialization = PartialSpec;
2794 PS->TemplateArgs = TemplateArgs;
2795 SpecializedTemplate = PS;
2796 }
2797
2798 /// Note that this variable template specialization is an instantiation
2799 /// of the given variable template.
2801 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2802 "Previously set to a variable template partial specialization!");
2803 SpecializedTemplate = TemplDecl;
2804 }
2805
2806 /// Retrieve the template argument list as written in the sources,
2807 /// if any.
2809 if (auto *Info =
2810 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2811 return Info->TemplateArgsAsWritten;
2812 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2813 }
2814
2815 /// Set the template argument list as written in the sources.
2816 void
2818 if (auto *Info =
2819 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2820 Info->TemplateArgsAsWritten = ArgsWritten;
2821 else
2822 ExplicitInfo = ArgsWritten;
2823 }
2824
2825 /// Set the template argument list as written in the sources.
2830
2831 /// Gets the location of the extern keyword, if present.
2833 if (auto *Info =
2834 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2835 return Info->ExternKeywordLoc;
2836 return SourceLocation();
2837 }
2838
2839 /// Sets the location of the extern keyword.
2841
2842 /// Gets the location of the template keyword, if present.
2844 if (auto *Info =
2845 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2846 return Info->TemplateKeywordLoc;
2847 return SourceLocation();
2848 }
2849
2850 /// Sets the location of the template keyword.
2852
2853 SourceRange getSourceRange() const override LLVM_READONLY;
2854
2855 void Profile(llvm::FoldingSetNodeID &ID) const {
2856 Profile(ID, TemplateArgs->asArray(), getASTContext());
2857 }
2858
2859 static void Profile(llvm::FoldingSetNodeID &ID,
2860 ArrayRef<TemplateArgument> TemplateArgs,
2861 const ASTContext &Context) {
2862 ID.AddInteger(TemplateArgs.size());
2863 for (const TemplateArgument &TemplateArg : TemplateArgs)
2864 TemplateArg.Profile(ID, Context);
2865 }
2866
2867 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2868
2869 static bool classofKind(Kind K) {
2870 return K >= firstVarTemplateSpecialization &&
2871 K <= lastVarTemplateSpecialization;
2872 }
2873};
2874
2875class VarTemplatePartialSpecializationDecl
2877 /// The list of template parameters
2878 TemplateParameterList *TemplateParams = nullptr;
2879
2880 /// The variable template partial specialization from which this
2881 /// variable template partial specialization was instantiated.
2882 ///
2883 /// The boolean value will be true to indicate that this variable template
2884 /// partial specialization was specialized at this level.
2885 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2886 InstantiatedFromMember;
2887
2888 VarTemplatePartialSpecializationDecl(
2889 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2891 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2893
2894 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2895 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2896 Context),
2897 InstantiatedFromMember(nullptr, false) {}
2898
2899 void anchor() override;
2900
2901public:
2902 friend class ASTDeclReader;
2903 friend class ASTDeclWriter;
2904
2905 static VarTemplatePartialSpecializationDecl *
2906 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2908 VarTemplateDecl *SpecializedTemplate, QualType T,
2909 TypeSourceInfo *TInfo, StorageClass S,
2911
2912 static VarTemplatePartialSpecializationDecl *
2914
2915 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2917 static_cast<VarTemplateSpecializationDecl *>(
2918 this)->getMostRecentDecl());
2919 }
2920
2921 /// Get the list of template parameters
2923 return TemplateParams;
2924 }
2925
2926 /// Get the template argument list of the template parameter list.
2928 getInjectedTemplateArgs(const ASTContext &Context) const {
2930 }
2931
2932 /// \brief All associated constraints of this partial specialization,
2933 /// including the requires clause and any constraints derived from
2934 /// constrained-parameters.
2935 ///
2936 /// The constraints in the resulting list are to be treated as if in a
2937 /// conjunction ("and").
2940 TemplateParams->getAssociatedConstraints(AC);
2941 }
2942
2944 return TemplateParams->hasAssociatedConstraints();
2945 }
2946
2947 /// \brief Retrieve the member variable template partial specialization from
2948 /// which this particular variable template partial specialization was
2949 /// instantiated.
2950 ///
2951 /// \code
2952 /// template<typename T>
2953 /// struct Outer {
2954 /// template<typename U> U Inner;
2955 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2956 /// };
2957 ///
2958 /// template int* Outer<float>::Inner<int*>;
2959 /// \endcode
2960 ///
2961 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2962 /// end up instantiating the partial specialization
2963 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2964 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2965 /// \c Outer<float>::Inner<U*>, this function would return
2966 /// \c Outer<T>::Inner<U*>.
2967 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2968 const auto *First =
2970 return First->InstantiatedFromMember.getPointer();
2971 }
2972
2973 void
2974 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2976 First->InstantiatedFromMember.setPointer(PartialSpec);
2977 }
2978
2979 /// Determines whether this variable template partial specialization
2980 /// was a specialization of a member partial specialization.
2981 ///
2982 /// In the following example, the member template partial specialization
2983 /// \c X<int>::Inner<T*> is a member specialization.
2984 ///
2985 /// \code
2986 /// template<typename T>
2987 /// struct X {
2988 /// template<typename U> U Inner;
2989 /// template<typename U> U* Inner<U*> = (U*)(0);
2990 /// };
2991 ///
2992 /// template<> template<typename T>
2993 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2994 /// \endcode
2996 const auto *First =
2998 return First->InstantiatedFromMember.getInt();
2999 }
3000
3001 /// Note that this member template is a specialization.
3004 assert(First->InstantiatedFromMember.getPointer() &&
3005 "Only member templates can be member template specializations");
3006 return First->InstantiatedFromMember.setInt(true);
3007 }
3008
3009 SourceRange getSourceRange() const override LLVM_READONLY;
3010
3011 void Profile(llvm::FoldingSetNodeID &ID) const {
3013 getASTContext());
3014 }
3015
3016 static void
3017 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3018 TemplateParameterList *TPL, const ASTContext &Context);
3019
3020 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3021
3022 static bool classofKind(Kind K) {
3023 return K == VarTemplatePartialSpecialization;
3024 }
3025};
3026
3027/// Declaration of a variable template.
3029protected:
3030 /// Data that is common to all of the declarations of a given
3031 /// variable template.
3033 /// The variable template specializations for this variable
3034 /// template, including explicit specializations and instantiations.
3035 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3036
3037 /// The variable template partial specializations for this variable
3038 /// template.
3039 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3041
3042 Common() = default;
3043 };
3044
3045 /// Retrieve the set of specializations of this variable template.
3046 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3047 getSpecializations() const;
3048
3049 /// Retrieve the set of partial specializations of this class
3050 /// template.
3051 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3053
3058
3059 CommonBase *newCommon(ASTContext &C) const override;
3060
3062 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3063 }
3064
3065public:
3066 friend class ASTDeclReader;
3067 friend class ASTDeclWriter;
3068
3069 /// Load any lazily-loaded specializations from the external source.
3070 void LoadLazySpecializations(bool OnlyPartial = false) const;
3071
3072 /// Get the underlying variable declarations of the template.
3074 return static_cast<VarDecl *>(TemplatedDecl);
3075 }
3076
3077 /// Returns whether this template declaration defines the primary
3078 /// variable pattern.
3082
3084
3085 /// Create a variable template node.
3088 TemplateParameterList *Params,
3089 VarDecl *Decl);
3090
3091 /// Create an empty variable template node.
3093
3094 /// Return the specialization with the provided arguments if it exists,
3095 /// otherwise return the insertion point.
3097 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3098
3099 /// Insert the specified specialization knowing that it is not already
3100 /// in. InsertPos must be obtained from findSpecialization.
3101 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3102
3109
3110 /// Retrieve the previous declaration of this variable template, or
3111 /// nullptr if no such declaration exists.
3113 return cast_or_null<VarTemplateDecl>(
3114 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3115 }
3117 return cast_or_null<VarTemplateDecl>(
3118 static_cast<const RedeclarableTemplateDecl *>(
3119 this)->getPreviousDecl());
3120 }
3121
3127 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3128 }
3129
3134
3135 /// Return the partial specialization with the provided arguments if it
3136 /// exists, otherwise return the insertion point.
3139 TemplateParameterList *TPL, void *&InsertPos);
3140
3141 /// Insert the specified partial specialization knowing that it is not
3142 /// already in. InsertPos must be obtained from findPartialSpecialization.
3144 void *InsertPos);
3145
3146 /// Retrieve the partial specializations as an ordered list.
3149
3150 /// Find a variable template partial specialization which was
3151 /// instantiated
3152 /// from the given member partial specialization.
3153 ///
3154 /// \param D a member variable template partial specialization.
3155 ///
3156 /// \returns the variable template partial specialization which was
3157 /// instantiated
3158 /// from the given member partial specialization, or nullptr if no such
3159 /// partial specialization exists.
3162
3164 using spec_range = llvm::iterator_range<spec_iterator>;
3165
3167 return spec_range(spec_begin(), spec_end());
3168 }
3169
3171 return makeSpecIterator(getSpecializations(), false);
3172 }
3173
3175 return makeSpecIterator(getSpecializations(), true);
3176 }
3177
3178 // Implement isa/cast/dyncast support
3179 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3180 static bool classofKind(Kind K) { return K == VarTemplate; }
3181};
3182
3183/// Declaration of a C++20 concept.
3184class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3185protected:
3187
3192public:
3194 DeclarationName Name,
3195 TemplateParameterList *Params,
3196 Expr *ConstraintExpr = nullptr);
3198
3200 return ConstraintExpr;
3201 }
3202
3203 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3204
3206
3207 SourceRange getSourceRange() const override LLVM_READONLY {
3208 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3209 ConstraintExpr ? ConstraintExpr->getEndLoc()
3210 : SourceLocation());
3211 }
3212
3213 bool isTypeConcept() const {
3214 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3215 }
3216
3219 }
3221 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3222 }
3223
3224 // Implement isa/cast/dyncast/etc.
3225 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3226 static bool classofKind(Kind K) { return K == Concept; }
3227
3228 friend class ASTReader;
3229 friend class ASTDeclReader;
3230 friend class ASTDeclWriter;
3231};
3232
3233// An implementation detail of ConceptSpecialicationExpr that holds the template
3234// arguments, so we can later use this to reconstitute the template arguments
3235// during constraint checking.
3236class ImplicitConceptSpecializationDecl final
3237 : public Decl,
3238 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3239 TemplateArgument> {
3240 unsigned NumTemplateArgs;
3241
3242 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3243 ArrayRef<TemplateArgument> ConvertedArgs);
3244 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3245
3246public:
3247 static ImplicitConceptSpecializationDecl *
3249 ArrayRef<TemplateArgument> ConvertedArgs);
3250 static ImplicitConceptSpecializationDecl *
3252 unsigned NumTemplateArgs);
3253
3255 return getTrailingObjects(NumTemplateArgs);
3256 }
3258
3259 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3260 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3261
3263 friend class ASTDeclReader;
3264};
3265
3266/// A template parameter object.
3267///
3268/// Template parameter objects represent values of class type used as template
3269/// arguments. There is one template parameter object for each such distinct
3270/// value used as a template argument across the program.
3271///
3272/// \code
3273/// struct A { int x, y; };
3274/// template<A> struct S;
3275/// S<A{1, 2}> s1;
3276/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3277/// \endcode
3278class TemplateParamObjectDecl : public ValueDecl,
3279 public Mergeable<TemplateParamObjectDecl>,
3280 public llvm::FoldingSetNode {
3281private:
3282 /// The value of this template parameter object.
3283 APValue Value;
3284
3285 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3286 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3287 T),
3288 Value(V) {}
3289
3290 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3291 const APValue &V);
3292 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3293 GlobalDeclID ID);
3294
3295 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3296 /// create these.
3297 friend class ASTContext;
3298 friend class ASTReader;
3299 friend class ASTDeclReader;
3300
3301public:
3302 /// Print this template parameter object in a human-readable format.
3303 void printName(llvm::raw_ostream &OS,
3304 const PrintingPolicy &Policy) const override;
3305
3306 /// Print this object as an equivalent expression.
3307 void printAsExpr(llvm::raw_ostream &OS) const;
3308 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3309
3310 /// Print this object as an initializer suitable for a variable of the
3311 /// object's type.
3312 void printAsInit(llvm::raw_ostream &OS) const;
3313 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3314
3315 const APValue &getValue() const { return Value; }
3316
3317 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3318 const APValue &V) {
3319 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3320 V.Profile(ID);
3321 }
3322 void Profile(llvm::FoldingSetNodeID &ID) {
3323 Profile(ID, getType(), getValue());
3324 }
3325
3326 TemplateParamObjectDecl *getCanonicalDecl() override {
3327 return getFirstDecl();
3328 }
3329 const TemplateParamObjectDecl *getCanonicalDecl() const {
3330 return getFirstDecl();
3331 }
3332
3333 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3334 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3335};
3336
3338 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3339 return PD;
3340 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3341 return PD;
3343}
3344
3346 auto *TD = dyn_cast<TemplateDecl>(D);
3347 return TD && (isa<ClassTemplateDecl>(TD) ||
3350 [&]() {
3351 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
3352 return TTP->templateParameterKind() == TNK_Type_template;
3353 return false;
3354 }())
3355 ? TD
3356 : nullptr;
3357}
3358
3359/// Check whether the template parameter is a pack expansion, and if so,
3360/// determine the number of parameters produced by that expansion. For instance:
3361///
3362/// \code
3363/// template<typename ...Ts> struct A {
3364/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3365/// };
3366/// \endcode
3367///
3368/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3369/// is not a pack expansion, so returns an empty Optional.
3371 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3372 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3373 return Num;
3374 }
3375
3376 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3377 if (NTTP->isExpandedParameterPack())
3378 return NTTP->getNumExpansionTypes();
3379 }
3380
3381 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3382 if (TTP->isExpandedParameterPack())
3383 return TTP->getNumExpansionTemplateParameters();
3384 }
3385
3386 return std::nullopt;
3387}
3388
3389/// Internal helper used by Subst* nodes to retrieve a parameter from the
3390/// AssociatedDecl, and the template argument substituted into it, if any.
3391std::tuple<NamedDecl *, TemplateArgument>
3392getReplacedTemplateParameter(Decl *D, unsigned Index);
3393
3394/// If we have a 'templated' declaration for a template, adjust 'D' to
3395/// refer to the actual template.
3396/// If we have an implicit instantiation, adjust 'D' to refer to template.
3397const Decl &adjustDeclToTemplate(const Decl &D);
3398
3399/// Represents an explicit instantiation of a template entity in source code.
3400///
3401/// \code
3402/// template void ns::foo<int>(int); // function template
3403/// extern template struct ns::S<int>; // class template (extern)
3404/// template int ns::bar<int>; // variable template
3405/// template void ns::S<int>::method(int); // member function
3406/// \endcode
3407class ExplicitInstantiationDecl final
3408 : public Decl,
3409 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3410 NestedNameSpecifierLoc,
3411 const ASTTemplateArgumentListInfo *> {
3412 friend class ASTDeclReader;
3413 friend class ASTDeclWriter;
3414 friend TrailingObjects;
3415
3416 /// The underlying specialization (low 3 bits: TSK).
3417 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3418
3419 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3420 /// Always non-null after construction.
3421 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3422 /// qualifier, template-name, and argument locations.
3423 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3424 /// - Function / variable templates: the declared type.
3425 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3426
3427 /// Location of the 'extern' keyword (invalid if not extern template).
3428 SourceLocation ExternLoc;
3429
3430 /// Location of the entity name (e.g., 'foo' in 'template void
3431 /// ns::foo<int>(int)').
3432 SourceLocation NameLoc;
3433
3434 enum TrailingFlags : unsigned {
3435 HasQualifierFlag = 1,
3436 HasArgsAsWrittenFlag = 2,
3437 };
3438
3439 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3440 return hasTrailingQualifier() ? 1 : 0;
3441 }
3442
3443 /// Raw access to the internal TypeSourceInfo. For class templates this is
3444 /// a TemplateSpecializationTypeLoc; for nested classes a TagTypeLoc.
3445 /// Public getTypeAsWritten() returns null for those cases.
3446 TypeSourceInfo *getRawTypeSourceInfo() const {
3447 return TypeAndFlags.getPointer();
3448 }
3449
3450 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3451 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3453 return nullptr;
3454 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3455 }
3456
3457 ExplicitInstantiationDecl(
3458 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3459 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3460 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3461 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3462
3463 ExplicitInstantiationDecl(EmptyShell Empty)
3465
3466public:
3467 static ExplicitInstantiationDecl *
3468 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3469 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3470 NestedNameSpecifierLoc QualifierLoc,
3471 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3472 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3474
3475 static ExplicitInstantiationDecl *
3476 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3477
3478 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3479
3480 SourceRange getSourceRange() const override LLVM_READONLY;
3481 SourceLocation getEndLoc() const LLVM_READONLY;
3482
3483 SourceLocation getExternLoc() const { return ExternLoc; }
3485 SourceLocation getNameLoc() const { return NameLoc; }
3486
3487 /// For class templates / nested classes, the tag keyword location is
3488 /// stored inside TypeSourceInfo; otherwise returns an invalid location.
3490
3491 /// Whether the qualifier is stored as a trailing object (function / variable
3492 /// templates) rather than inside TypeSourceInfo (class templates / nested
3493 /// classes).
3495 return TypeAndFlags.getInt() & HasQualifierFlag;
3496 }
3498 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3499 }
3500
3501 /// Returns the qualifier regardless of where it is stored.
3502 /// For class templates / nested classes, it is extracted from TypeSourceInfo
3503 /// (TemplateSpecializationTypeLoc or TagTypeLoc).
3504 /// For function / variable templates, it comes from a trailing object.
3506
3507 /// Number of explicit template arguments, regardless of storage.
3508 /// For class templates they come from TemplateSpecializationTypeLoc;
3509 /// for function / variable templates from trailing
3510 /// ASTTemplateArgumentListInfo.
3511 unsigned getNumTemplateArgs() const;
3512 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3515
3516 /// For function / variable templates, returns the declared type (return type
3517 /// or variable type). For class templates and nested classes returns null —
3518 /// the qualifier, tag keyword, and template arguments are accessible via
3519 /// getQualifierLoc(), getTagKWLoc(), and getTemplateArg().
3521
3523 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3524 }
3525
3526 bool isExternTemplate() const { return ExternLoc.isValid(); }
3527
3528 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3529 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3530};
3531
3532} // namespace clang
3533
3534#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:475
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.
Defines the clang::TemplateNameKind enum.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
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:227
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)
bool isPackProducingBuiltinTemplate() const
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CXXRecordDecl * getMostRecentDecl()
Definition DeclCXX.h:539
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition DeclCXX.cpp:2060
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:124
CXXRecordDecl * getDefinitionOrSelf() const
Definition DeclCXX.h:555
friend class DeclContext
Definition DeclCXX.h:266
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 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
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 the given declaration.
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.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
SpecIterator< ClassTemplateSpecializationDecl > spec_iterator
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
void setCommonPtr(Common *C)
spec_range specializations() const
friend class TemplateDeclInstantiator
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...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setMemberSpecialization()
Note that this member template is a specialization.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
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.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
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, GlobalDeclID ID)
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 setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
static bool classof(const Decl *D)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
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.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
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...
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 setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
ClassTemplateSpecializationDecl * getDefinitionOrSelf() const
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
void setDefinition(Expr *E)
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)
friend class ASTReader
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
friend class ASTDeclReader
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasDefinition() const
static bool classof(const Decl *D)
friend class ASTDeclWriter
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:130
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
virtual Decl * getPreviousDeclImpl()
Implementation of getPreviousDecl(), to be overridden by any subclass that has a redeclaration chain.
Definition DeclBase.h:1008
Kind
Lists the kind of concrete classes of Decl.
Definition DeclBase.h:89
virtual Decl * getNextRedeclarationImpl()
Returns the next redeclaration or itself if this is the only decl.
Definition DeclBase.h:1004
SourceLocation getLocation() const
Definition DeclBase.h:447
virtual Decl * getMostRecentDeclImpl()
Implementation of getMostRecentDecl(), to be overridden by any subclass that has a redeclaration chai...
Definition DeclBase.h:1012
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:931
friend class DeclContext
Definition DeclBase.h:260
Kind getKind() const
Definition DeclBase.h:450
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL)
Definition Decl.h:800
Storage for a default argument.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
bool isSet() const
Determine whether there is a default argument for this parameter.
ArgType get() const
Get the default argument's value.
void set(ArgType Arg)
Set the default argument.
void clear()
Remove the default argument, even if it was inherited.
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getEndLoc() const LLVM_READONLY
static ExplicitInstantiationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags)
TypeSourceInfo * getTypeAsWritten() const
For function / variable templates, returns the declared type (return type or variable type).
TemplateSpecializationKind getTemplateSpecializationKind() const
SourceLocation getExternLoc() const
SourceLocation getTemplateArgsLAngleLoc() const
TemplateArgumentLoc getTemplateArg(unsigned I) const
unsigned getNumTemplateArgs() const
Number of explicit template arguments, regardless of storage.
bool hasTrailingQualifier() const
Whether the qualifier is stored as a trailing object (function / variable templates) rather than insi...
SourceLocation getTemplateArgsRAngleLoc() const
NamedDecl * getSpecialization() const
SourceLocation getTagKWLoc() const
For class templates / nested classes, the tag keyword location is stored inside TypeSourceInfo; other...
static bool classof(const Decl *D)
NestedNameSpecifierLoc getQualifierLoc() const
Returns the qualifier regardless of where it is stored.
SourceLocation getTemplateLoc() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getNameLoc() const
This represents one expression.
Definition Expr.h:112
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
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),...
TemplateParameterList * getTemplateParameterList(unsigned i) const
static bool classofKind(Kind K)
unsigned getNumTemplateParameters() const
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
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:2018
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2332
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition Decl.h:2387
bool isInstantiatedFromMemberTemplate() const
Definition Decl.h:2384
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D)
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
spec_range specializations() const
SpecIterator< FunctionTemplateSpecializationInfo > spec_iterator
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
bool isCompatibleWithDefinition() const
const FunctionTemplateDecl * getMostRecentDecl() const
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 ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
void Profile(llvm::FoldingSetNodeID &ID)
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
Provides information a specialization of a member of a class template, which may be a member function...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
TemplateParamObjectDecl * getFirstDecl()
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
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)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the associated-constraints of this template parameter.
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.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
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.
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)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition TypeBase.h:937
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
redeclarable_base::redecl_iterator redecl_iterator
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
const RedeclarableTemplateDecl * getCanonicalDecl() const
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redeclarable_base::redecl_range redecl_range
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
static bool classof(const Decl *D)
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
static bool classofKind(Kind K)
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getNextRedeclaration() const
RedeclarableTemplateDecl * getPreviousDecl()
llvm::iterator_range< redecl_iterator > redecl_range
RedeclarableTemplateDecl * getMostRecentDecl()
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
TagTypeKind TagKind
Definition Decl.h:3740
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3831
A convenient class for passing around template argument information.
A template argument list.
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * TemplatedDecl
TemplateParameterList * TemplateParams
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
friend class ASTDeclReader
void setTemplateParameters(TemplateParameterList *TParams)
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static bool classof(const Decl *D)
friend class ASTDeclWriter
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
static bool classofKind(Kind K)
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)
friend class ASTContext
Only ASTContext::getTemplateParamObjectDecl and deserialization create these.
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.
const_iterator end() const
NamedDecl * getParam(unsigned Idx)
SourceRange getSourceRange() const LLVM_READONLY
const_iterator begin() const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
friend class FixedSizeTemplateParameterListStorage
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.
NamedDecl ** iterator
Iterates through the template parameters in this list.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
size_t numTrailingObjects(OverloadToken< Expr * >) const
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
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.
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
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< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
ArrayRef< const NamedDecl * > asArray() const
Defines the position of a template parameter within a template parameter list.
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool wasDeclaredWithTypename() const
Whether this template template parameter was declared with the 'typename' keyword.
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
TemplateNameKind templateParameterKind() const
static bool classof(const Decl *D)
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
void setInheritedDefaultArgument(const ASTContext &C, TemplateTemplateParmDecl *Prev)
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
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 setDeclaredWithTypename(bool withTypename)
Set whether this template template parameter was declared with the 'typename' or 'class' keyword.
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...
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.
const TemplateArgumentLoc & 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.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint, UnsignedOrNone ArgPackSubstIndex)
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
friend class Sema
Sema creates these on the stack during auto type deduction.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
UnsignedOrNone getNumExpansionParameters() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
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.
void removeDefaultArgument()
Removes the default argument of this template parameter.
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the associated-constraints of 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 setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
static bool classofKind(Kind K)
static bool classof(const Decl *D)
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:3706
Declaration of an alias template.
static bool classof(const Decl *D)
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID 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)
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:227
friend class ASTContext
Definition Decl.h:3532
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL=SourceLocation())
Definition Decl.h:3547
A container of type source information.
Definition TypeBase.h:8416
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2961
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
A set of unresolved declarations.
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T)
Definition Decl.h:718
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:924
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition Decl.cpp:2239
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:2758
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...
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
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty 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 ...
SpecIterator< VarTemplateSpecializationDecl > spec_iterator
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
spec_range specializations() const
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.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
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.
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
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...
static bool classof(const Decl *D)
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...
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
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...
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
VarTemplateSpecializationDecl * getMostRecentDecl()
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.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition Specifiers.h:213
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Definition Template.h:50
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition Decl.cpp:76
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
NamedDecl * getAsNamedDecl(TemplateParameter P)
bool isPackProducingBuiltinTemplateName(TemplateName N)
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:249
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
void * allocateDefaultArgStorageChain(const ASTContext &C)
TemplateDecl * getAsTypeTemplateDecl(Decl *D)
OptionalUnsigned< unsigned > UnsignedOrNone
@ ExplicitInstantiation
We are parsing an explicit instantiation.
Definition Parser.h:85
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition Builtins.h:491
@ FunctionTemplate
The name was classified as a function template name.
Definition Sema.h:587
@ Concept
The name was classified as a concept name.
Definition Sema.h:591
@ VarTemplate
The name was classified as a variable template name.
Definition Sema.h:585
llvm::PointerUnion< const ASTTemplateArgumentListInfo *, ExplicitInstantiationInfo * > SpecializationOrInstantiationInfo
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
const Decl & adjustDeclToTemplate(const Decl &D)
If we have a 'templated' declaration for a template, adjust 'D' to refer to the actual template.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition Specifiers.h:189
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:5986
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition Specifiers.h:220
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
CanQualType CanonInjectedTST
The Injected Template Specialization Type for this declaration.
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...
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
SourceLocation ExternKeywordLoc
The location of the extern keyword.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
SourceLocation TemplateKeywordLoc
The location of the template keyword.
Data that is common to all of the declarations of a given function template.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Describes how types, statements, expressions, and declarations should be printed.
llvm::PointerIntPair< RedeclarableTemplateDecl *, 1, bool > InstantiatedFromMember
The template from which this was most directly instantiated (or null).
static ArrayRef< TemplateArgument > getTemplateArgs(FunctionTemplateSpecializationInfo *I)
static ArrayRef< TemplateArgument > getTemplateArgs(EntryType *D)
static DeclType * getDecl(EntryType *D)
SpecIterator(typename llvm::FoldingSetVector< EntryType >::iterator SetIter)
Data that is common to all of the declarations of a given variable template.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > PartialSpecializations
The variable template partial specializations for this variable template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > Specializations
The variable template specializations for this variable template, including explicit specializations ...