clang 24.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"
26#include "clang/AST/Type.h"
27#include "clang/Basic/LLVM.h"
31#include "llvm/ADT/ArrayRef.h"
32#include "llvm/ADT/FoldingSet.h"
33#include "llvm/ADT/PointerIntPair.h"
34#include "llvm/ADT/PointerUnion.h"
35#include "llvm/ADT/iterator.h"
36#include "llvm/ADT/iterator_range.h"
37#include "llvm/Support/Casting.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/TrailingObjects.h"
40#include <cassert>
41#include <cstddef>
42#include <cstdint>
43#include <iterator>
44#include <optional>
45#include <utility>
46
47namespace clang {
48
52class Expr;
54class IdentifierInfo;
56class TemplateDecl;
59class ConceptDecl;
61class VarTemplateDecl;
63
64/// Stores a template parameter of any kind.
66 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
68
70
71/// Stores a list of template parameters for a TemplateDecl and its
72/// derived classes.
74 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
75 Expr *> {
76 /// The template argument list of the template parameter list.
77 TemplateArgument *InjectedArgs = nullptr;
78
79 /// The location of the 'template' keyword.
80 SourceLocation TemplateLoc;
81
82 /// The locations of the '<' and '>' angle brackets.
83 SourceLocation LAngleLoc, RAngleLoc;
84
85 /// The number of template parameters in this template
86 /// parameter list.
87 unsigned NumParams : 29;
88
89 /// Whether this template parameter list contains an unexpanded parameter
90 /// pack.
91 LLVM_PREFERRED_TYPE(bool)
92 unsigned ContainsUnexpandedParameterPack : 1;
93
94 /// Whether this template parameter list has a requires clause.
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned HasRequiresClause : 1;
97
98 /// Whether any of the template parameters has constrained-parameter
99 /// constraint-expression.
100 LLVM_PREFERRED_TYPE(bool)
101 unsigned HasConstrainedParameters : 1;
102
103protected:
105 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
106 SourceLocation RAngleLoc, Expr *RequiresClause);
107
108 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
109 return NumParams;
110 }
111
112 size_t numTrailingObjects(OverloadToken<Expr *>) const {
113 return HasRequiresClause ? 1 : 0;
114 }
115
116public:
117 template <size_t N, bool HasRequiresClause>
120
122 SourceLocation TemplateLoc,
123 SourceLocation LAngleLoc,
125 SourceLocation RAngleLoc,
126 Expr *RequiresClause);
127
128 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
129
130 /// Iterates through the template parameters in this list.
131 using iterator = NamedDecl **;
132
133 /// Iterates through the template parameters in this list.
134 using const_iterator = NamedDecl * const *;
135
136 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
137 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
138 iterator end() { return begin() + NumParams; }
139 const_iterator end() const { return begin() + NumParams; }
140
141 unsigned size() const { return NumParams; }
142 bool empty() const { return NumParams == 0; }
143
146
147 NamedDecl* getParam(unsigned Idx) {
148 assert(Idx < size() && "Template parameter index out-of-range");
149 return begin()[Idx];
150 }
151 const NamedDecl* getParam(unsigned Idx) const {
152 assert(Idx < size() && "Template parameter index out-of-range");
153 return begin()[Idx];
154 }
155
156 /// Returns the minimum number of arguments needed to form a
157 /// template specialization.
158 ///
159 /// This may be fewer than the number of template parameters, if some of
160 /// the parameters have default arguments or if there is a parameter pack.
161 unsigned getMinRequiredArguments() const;
162
163 /// Get the depth of this template parameter list in the set of
164 /// template parameter lists.
165 ///
166 /// The first template parameter list in a declaration will have depth 0,
167 /// the second template parameter list will have depth 1, etc.
168 unsigned getDepth() const;
169
170 /// Determine whether this template parameter list contains an
171 /// unexpanded parameter pack.
173
174 /// Determine whether this template parameter list contains a parameter pack.
175 bool hasParameterPack() const {
176 for (const NamedDecl *P : asArray())
177 if (P->isParameterPack())
178 return true;
179 return false;
180 }
181
182 /// The constraint-expression of the associated requires-clause.
184 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
185 }
186
187 /// The constraint-expression of the associated requires-clause.
188 const Expr *getRequiresClause() const {
189 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
190 }
191
192 /// \brief All associated constraints derived from this template parameter
193 /// list, including the requires clause and any constraints derived from
194 /// constrained-parameters.
195 ///
196 /// The constraints in the resulting list are to be treated as if in a
197 /// conjunction ("and").
200
202
203 /// Get the template argument list of the template parameter list.
205
206 SourceLocation getTemplateLoc() const { return TemplateLoc; }
207 SourceLocation getLAngleLoc() const { return LAngleLoc; }
208 SourceLocation getRAngleLoc() const { return RAngleLoc; }
209
210 SourceRange getSourceRange() const LLVM_READONLY {
211 return SourceRange(TemplateLoc, RAngleLoc);
212 }
213
214 void print(raw_ostream &Out, const ASTContext &Context,
215 bool OmitTemplateKW = false) const;
216 void print(raw_ostream &Out, const ASTContext &Context,
217 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
218
220 const TemplateParameterList *TPL,
221 unsigned Idx);
222};
223
224/// Stores a list of template parameters and the associated
225/// requires-clause (if any) for a TemplateDecl and its derived classes.
226/// Suitable for creating on the stack.
227template <size_t N, bool HasRequiresClause>
229 : public TemplateParameterList::FixedSizeStorageOwner {
230 typename TemplateParameterList::FixedSizeStorage<
231 NamedDecl *, Expr *>::with_counts<
232 N, HasRequiresClause ? 1u : 0u
233 >::type storage;
234
235public:
237 SourceLocation TemplateLoc,
238 SourceLocation LAngleLoc,
240 SourceLocation RAngleLoc,
241 Expr *RequiresClause)
242 : FixedSizeStorageOwner(
243 (assert(N == Params.size()),
244 assert(HasRequiresClause == (RequiresClause != nullptr)),
245 new (static_cast<void *>(&storage)) TemplateParameterList(C,
246 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
247};
248
249/// A template argument list.
250class TemplateArgumentList final
251 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
252 /// The number of template arguments in this template
253 /// argument list.
254 unsigned NumArguments;
255
256 // Constructs an instance with an internal Argument list, containing
257 // a copy of the Args array. (Called by CreateCopy)
258 TemplateArgumentList(ArrayRef<TemplateArgument> Args);
259
260public:
262
263 TemplateArgumentList(const TemplateArgumentList &) = delete;
264 TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
265
266 /// Create a new template argument list that copies the given set of
267 /// template arguments.
268 static TemplateArgumentList *CreateCopy(ASTContext &Context,
270
271 /// Retrieve the template argument at a given index.
272 const TemplateArgument &get(unsigned Idx) const {
273 assert(Idx < NumArguments && "Invalid template argument index");
274 return data()[Idx];
275 }
276
277 /// Retrieve the template argument at a given index.
278 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
279
280 /// Produce this as an array ref.
282 return getTrailingObjects(size());
283 }
284
285 /// Retrieve the number of template arguments in this
286 /// template argument list.
287 unsigned size() const { return NumArguments; }
288
289 /// Retrieve a pointer to the template argument list.
290 const TemplateArgument *data() const { return getTrailingObjects(); }
291};
292
294
295/// Storage for a default argument. This is conceptually either empty, or an
296/// argument value, or a pointer to a previous declaration that had a default
297/// argument.
298///
299/// However, this is complicated by modules: while we require all the default
300/// arguments for a template to be equivalent, there may be more than one, and
301/// we need to track all the originating parameters to determine if the default
302/// argument is visible.
303template<typename ParmDecl, typename ArgType>
305 /// Storage for both the value *and* another parameter from which we inherit
306 /// the default argument. This is used when multiple default arguments for a
307 /// parameter are merged together from different modules.
308 struct Chain {
309 ParmDecl *PrevDeclWithDefaultArg;
310 ArgType Value;
311 };
312 static_assert(sizeof(Chain) == sizeof(void *) * 2,
313 "non-pointer argument type?");
314
315 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
316
317 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
318 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
319 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
320 Parm = Prev;
321 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
322 "should only be one level of indirection");
323 return Parm;
324 }
325
326public:
327 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
328
329 /// Determine whether there is a default argument for this parameter.
330 bool isSet() const { return !ValueOrInherited.isNull(); }
331
332 /// Determine whether the default argument for this parameter was inherited
333 /// from a previous declaration of the same entity.
334 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
335
336 /// Get the default argument's value. This does not consider whether the
337 /// default argument is visible.
338 ArgType get() const {
339 const DefaultArgStorage *Storage = this;
340 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
341 Storage = &Prev->getDefaultArgStorage();
342 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
343 return C->Value;
344 return cast<ArgType>(Storage->ValueOrInherited);
345 }
346
347 /// Get the parameter from which we inherit the default argument, if any.
348 /// This is the parameter on which the default argument was actually written.
349 const ParmDecl *getInheritedFrom() const {
350 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
351 return D;
352 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
353 return C->PrevDeclWithDefaultArg;
354 return nullptr;
355 }
356
357 /// Set the default argument.
358 void set(ArgType Arg) {
359 assert(!isSet() && "default argument already set");
360 ValueOrInherited = Arg;
361 }
362
363 /// Set that the default argument was inherited from another parameter.
364 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
365 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
366 if (!isSet())
367 ValueOrInherited = InheritedFrom;
368 else if ([[maybe_unused]] auto *D =
369 dyn_cast<ParmDecl *>(ValueOrInherited)) {
370 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
371 ValueOrInherited =
372 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
373 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
374 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
375 InheritedFrom));
376 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
377 } else
378 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
379 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
380 }
381
382 /// Remove the default argument, even if it was inherited.
383 void clear() {
384 ValueOrInherited = ArgType();
385 }
386};
387
388//===----------------------------------------------------------------------===//
389// Kinds of Templates
390//===----------------------------------------------------------------------===//
391
392/// \brief The base class of all kinds of template declarations (e.g.,
393/// class, function, etc.).
394///
395/// The TemplateDecl class stores the list of template parameters and a
396/// reference to the templated scoped declaration: the underlying AST node.
397class TemplateDecl : public NamedDecl {
398 void anchor() override;
399
400protected:
401 // Construct a template decl with name, parameters, and templated element.
404
405 // Construct a template decl with the given name and parameters.
406 // Used when there is no templated element (e.g., for tt-params).
408 TemplateParameterList *Params)
409 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
410
411public:
412 friend class ASTDeclReader;
413 friend class ASTDeclWriter;
414
415 /// Get the list of template parameters
419
420 /// \brief Get the total constraint-expression associated with this template,
421 /// including constraint-expressions derived from the requires-clause,
422 /// trailing requires-clause (for functions and methods) and constrained
423 /// template parameters.
426
427 bool hasAssociatedConstraints() const;
428
429 /// Get the underlying, templated declaration.
431
432 // Should a specialization behave like an alias for another type.
433 bool isTypeAlias() const;
434
435 // Implement isa/cast/dyncast/etc.
436 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
437
438 static bool classofKind(Kind K) {
439 return K >= firstTemplate && K <= lastTemplate;
440 }
441
442 SourceRange getSourceRange() const override LLVM_READONLY {
443 return SourceRange(getTemplateParameters()->getTemplateLoc(),
444 TemplatedDecl->getSourceRange().getEnd());
445 }
446
447protected:
450
451public:
453 TemplateParams = TParams;
454 }
455
456 /// Initialize the underlying templated declaration.
457 void init(NamedDecl *NewTemplatedDecl) {
458 if (TemplatedDecl)
459 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
460 else
461 TemplatedDecl = NewTemplatedDecl;
462 }
463};
464
465/// Provides information about a function template specialization,
466/// which is a FunctionDecl that has been explicitly specialization or
467/// instantiated from a function template.
468class FunctionTemplateSpecializationInfo final
469 : public llvm::FoldingSetNode,
470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
471 MemberSpecializationInfo *> {
472 /// The function template specialization that this structure describes and a
473 /// flag indicating if the function is a member specialization.
474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
475
476 /// The function template from which this function template
477 /// specialization was generated.
478 ///
479 /// The two bits contain the top 4 values of TemplateSpecializationKind.
480 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
481
482public:
483 /// The template arguments used to produce the function template
484 /// specialization from the function template.
486
487 /// The template arguments as written in the sources, if provided.
488 /// FIXME: Normally null; tail-allocate this.
490
491 /// The point at which this function template specialization was
492 /// first instantiated.
494
495private:
496 FunctionTemplateSpecializationInfo(
497 FunctionDecl *FD, FunctionTemplateDecl *Template,
499 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
501 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
502 TemplateArguments(TemplateArgs),
503 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
505 if (MSInfo)
506 getTrailingObjects()[0] = MSInfo;
507 }
508
509 size_t numTrailingObjects() const { return Function.getInt(); }
510
511public:
513
514 static FunctionTemplateSpecializationInfo *
517 const TemplateArgumentListInfo *TemplateArgsAsWritten,
519
520 /// Retrieve the declaration of the function template specialization.
521 FunctionDecl *getFunction() const { return Function.getPointer(); }
522
523 /// Retrieve the template from which this function was specialized.
524 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
525
526 /// Determine what kind of template specialization this is.
528 return (TemplateSpecializationKind)(Template.getInt() + 1);
529 }
530
534
535 /// True if this declaration is an explicit specialization,
536 /// explicit instantiation declaration, or explicit instantiation
537 /// definition.
542
543 /// Set the template specialization kind.
545 assert(TSK != TSK_Undeclared &&
546 "Cannot encode TSK_Undeclared for a function template specialization");
547 Template.setInt(TSK - 1);
548 }
549
550 /// Retrieve the first point of instantiation of this function
551 /// template specialization.
552 ///
553 /// The point of instantiation may be an invalid source location if this
554 /// function has yet to be instantiated.
558
559 /// Set the (first) point of instantiation of this function template
560 /// specialization.
564
565 /// Get the specialization info if this function template specialization is
566 /// also a member specialization:
567 ///
568 /// \code
569 /// template<typename> struct A {
570 /// template<typename> void f();
571 /// template<> void f<int>();
572 /// };
573 /// \endcode
574 ///
575 /// Here, A<int>::f<int> is a function template specialization that is
576 /// an explicit specialization of A<int>::f, but it's also a member
577 /// specialization (an implicit instantiation in this case) of A::f<int>.
578 /// Further:
579 ///
580 /// \code
581 /// template<> template<> void A<int>::f<int>() {}
582 /// \endcode
583 ///
584 /// ... declares a function template specialization that is an explicit
585 /// specialization of A<int>::f, and is also an explicit member
586 /// specialization of A::f<int>.
587 ///
588 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
589 /// need not be the same as that returned by getTemplateSpecializationKind(),
590 /// and represents the relationship between the function and the class-scope
591 /// explicit specialization in the original templated class -- whereas our
592 /// TemplateSpecializationKind represents the relationship between the
593 /// function and the function template, and should always be
594 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
596 return numTrailingObjects() ? getTrailingObjects()[0] : nullptr;
597 }
598
599 void Profile(llvm::FoldingSetNodeID &ID) {
600 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
601 }
602
603 static void
604 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
605 const ASTContext &Context) {
606 ID.AddInteger(TemplateArgs.size());
607 for (const TemplateArgument &TemplateArg : TemplateArgs)
608 TemplateArg.Profile(ID, Context);
609 }
610};
611
612/// Provides information a specialization of a member of a class
613/// template, which may be a member function, static data member,
614/// member class or member enumeration.
616 // The member declaration from which this member was instantiated, and the
617 // manner in which the instantiation occurred (in the lower two bits).
618 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
619
620 // The point at which this member was first instantiated.
621 SourceLocation PointOfInstantiation;
622
623public:
624 explicit
627 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
628 assert(TSK != TSK_Undeclared &&
629 "Cannot encode undeclared template specializations for members");
630 }
631
632 /// Retrieve the member declaration from which this member was
633 /// instantiated.
634 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
635
636 /// Determine what kind of template specialization this is.
638 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
639 }
640
644
645 /// Set the template specialization kind.
647 assert(TSK != TSK_Undeclared &&
648 "Cannot encode undeclared template specializations for members");
649 MemberAndTSK.setInt(TSK - 1);
650 }
651
652 /// Retrieve the first point of instantiation of this member.
653 /// If the point of instantiation is an invalid location, then this member
654 /// has not yet been instantiated.
656 return PointOfInstantiation;
657 }
658
659 /// Set the first point of instantiation.
661 PointOfInstantiation = POI;
662 }
663};
664
665/// Provides information about a dependent function-template
666/// specialization declaration.
667///
668/// This is used for function templates explicit specializations declared
669/// within class templates:
670///
671/// \code
672/// template<typename> struct A {
673/// template<typename> void f();
674/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
675/// };
676/// \endcode
677///
678/// As well as dependent friend declarations naming function template
679/// specializations declared within class templates:
680///
681/// \code
682/// template <class T> void foo(T);
683/// template <class T> class A {
684/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
685/// };
686/// \endcode
687class DependentFunctionTemplateSpecializationInfo final
688 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
689 FunctionTemplateDecl *> {
690 friend TrailingObjects;
691
692 /// The number of candidates for the primary template.
693 unsigned NumCandidates;
694
695 DependentFunctionTemplateSpecializationInfo(
696 const UnresolvedSetImpl &Candidates,
697 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
698
699public:
700 /// The template arguments as written in the sources, if provided.
702
703 static DependentFunctionTemplateSpecializationInfo *
704 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
705 const TemplateArgumentListInfo *TemplateArgs);
706
707 /// Returns the candidates for the primary function template.
709 return getTrailingObjects(NumCandidates);
710 }
711};
712
713/// Declaration of a redeclarable template.
715 public Redeclarable<RedeclarableTemplateDecl>
716{
717 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
718
720 return getNextRedeclaration();
721 }
722
724 return getPreviousDecl();
725 }
726
728 return getMostRecentDecl();
729 }
730
731 void anchor() override;
732
733protected:
734 template <typename EntryType> struct SpecEntryTraits {
735 using DeclType = EntryType;
736
737 static DeclType *getDecl(EntryType *D) {
738 return D;
739 }
740
742 return D->getTemplateArgs().asArray();
743 }
744 };
745
746 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
747 typename DeclType = typename SETraits::DeclType>
749 : llvm::iterator_adaptor_base<
750 SpecIterator<EntryType, SETraits, DeclType>,
751 typename llvm::FoldingSetVector<EntryType>::iterator,
752 typename std::iterator_traits<typename llvm::FoldingSetVector<
753 EntryType>::iterator>::iterator_category,
754 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
755 SpecIterator() = default;
756 explicit SpecIterator(
757 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
758 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
759
760 DeclType *operator*() const {
761 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
762 }
763
764 DeclType *operator->() const { return **this; }
765 };
766
767 template <typename EntryType>
768 static SpecIterator<EntryType>
769 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
770 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
771 }
772
773 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
774
776 TemplateParameterList *TPL = nullptr) const;
777
778 template <class EntryType, typename... ProfileArguments>
780 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
781 llvm::FoldingSetInsertToken &InsertToken,
782 ProfileArguments... ProfileArgs);
783
784 template <class EntryType, typename... ProfileArguments>
786 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
787 llvm::FoldingSetInsertToken &InsertToken,
788 ProfileArguments... ProfileArgs);
789
790 template <class Derived, class EntryType>
791 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
792 EntryType *Entry,
793 llvm::FoldingSetInsertToken InsertToken);
794
795 struct CommonBase {
797
798 /// The template from which this was most
799 /// directly instantiated (or null).
800 ///
801 /// The boolean value indicates whether this template
802 /// was explicitly specialized.
803 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
805 };
806
807 /// Pointer to the common data shared by all declarations of this
808 /// template.
809 mutable CommonBase *Common = nullptr;
810
811 /// Retrieves the "common" pointer shared by all (re-)declarations of
812 /// the same template. Calling this routine may implicitly allocate memory
813 /// for the common pointer.
814 CommonBase *getCommonPtr() const;
815
816 virtual CommonBase *newCommon(ASTContext &C) const = 0;
817
818 // Construct a template decl with name, parameters, and templated element.
822 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
823
824public:
825 friend class ASTDeclReader;
826 friend class ASTDeclWriter;
827 friend class ASTReader;
828 template <class decl_type> friend class RedeclarableTemplate;
829
830 /// Retrieves the canonical declaration of this template.
832 return getFirstDecl();
833 }
835 return getFirstDecl();
836 }
837
838 /// Determines whether this template was a specialization of a
839 /// member template.
840 ///
841 /// In the following example, the function template \c X<int>::f and the
842 /// member template \c X<int>::Inner are member specializations.
843 ///
844 /// \code
845 /// template<typename T>
846 /// struct X {
847 /// template<typename U> void f(T, U);
848 /// template<typename U> struct Inner;
849 /// };
850 ///
851 /// template<> template<typename T>
852 /// void X<int>::f(int, T);
853 /// template<> template<typename T>
854 /// struct X<int>::Inner { /* ... */ };
855 /// \endcode
857 return getCommonPtr()->InstantiatedFromMember.getInt();
858 }
859
860 /// Note that this member template is a specialization.
862 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
863 "Only member templates can be member template specializations");
864 getCommonPtr()->InstantiatedFromMember.setInt(true);
865 }
866
867 /// Retrieve the member template from which this template was
868 /// instantiated, or nullptr if this template was not instantiated from a
869 /// member template.
870 ///
871 /// A template is instantiated from a member template when the member
872 /// template itself is part of a class template (or member thereof). For
873 /// example, given
874 ///
875 /// \code
876 /// template<typename T>
877 /// struct X {
878 /// template<typename U> void f(T, U);
879 /// };
880 ///
881 /// void test(X<int> x) {
882 /// x.f(1, 'a');
883 /// };
884 /// \endcode
885 ///
886 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
887 /// template
888 ///
889 /// \code
890 /// template<typename U> void X<int>::f(int, U);
891 /// \endcode
892 ///
893 /// which was itself created during the instantiation of \c X<int>. Calling
894 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
895 /// retrieve the FunctionTemplateDecl for the original template \c f within
896 /// the class template \c X<T>, i.e.,
897 ///
898 /// \code
899 /// template<typename T>
900 /// template<typename U>
901 /// void X<T>::f(T, U);
902 /// \endcode
906
908 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
909 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
910 }
911
912 /// Retrieve the "injected" template arguments that correspond to the
913 /// template parameters of this template.
914 ///
915 /// Although the C++ standard has no notion of the "injected" template
916 /// arguments for a template, the notion is convenient when
917 /// we need to perform substitutions inside the definition of a template.
919 getInjectedTemplateArgs(const ASTContext &Context) const {
921 }
922
924 using redecl_iterator = redeclarable_base::redecl_iterator;
925
932
933 // Implement isa/cast/dyncast/etc.
934 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
935
936 static bool classofKind(Kind K) {
937 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
938 }
939};
940
941template <> struct RedeclarableTemplateDecl::
942SpecEntryTraits<FunctionTemplateSpecializationInfo> {
944
948
953};
954
955/// Declaration of a template function.
957protected:
958 friend class FunctionDecl;
959
960 /// Data that is common to all of the declarations of a given
961 /// function template.
963 /// The function template specializations for this function
964 /// template, including explicit specializations and instantiations.
965 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
966
967 Common() = default;
968 };
969
975
976 CommonBase *newCommon(ASTContext &C) const override;
977
979 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
980 }
981
982 /// Retrieve the set of function template specializations of this
983 /// function template.
984 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
985 getSpecializations() const;
986
987 /// Add a specialization of this function template.
988 ///
989 /// \param InsertToken Insert token, must have been retrieved by an earlier
990 /// call to findSpecialization().
992 llvm::FoldingSetInsertToken InsertToken);
993
994public:
995 friend class ASTDeclReader;
996 friend class ASTDeclWriter;
997
998 /// Load any lazily-loaded specializations from the external source.
999 void LoadLazySpecializations() const;
1000
1001 /// Get the underlying function declaration of the template.
1003 return static_cast<FunctionDecl *>(TemplatedDecl);
1004 }
1005
1006 /// Returns whether this template declaration defines the primary
1007 /// pattern.
1011
1016
1017 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1018 // except this is per declaration, while the redeclarable field is
1019 // per chain. This indicates a template redeclaration which
1020 // is compatible with the definition, in the non-trivial case
1021 // where this is not already a definition.
1022 // This is only really needed for instantiating the definition of friend
1023 // function templates, which can have redeclarations in different template
1024 // contexts.
1025 // The bit is actually stored in the FunctionDecl for space efficiency
1026 // reasons.
1031
1032 /// Return the specialization with the provided arguments if it exists,
1033 /// otherwise return the insertion point.
1035 llvm::FoldingSetInsertToken &InsertToken);
1036
1045
1046 /// Retrieve the previous declaration of this function template, or
1047 /// nullptr if no such declaration exists.
1049 return cast_or_null<FunctionTemplateDecl>(
1050 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1051 }
1053 return cast_or_null<FunctionTemplateDecl>(
1054 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1055 }
1056
1063 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1064 }
1065
1067 return cast_or_null<FunctionTemplateDecl>(
1069 }
1070
1072 using spec_range = llvm::iterator_range<spec_iterator>;
1073
1075 return spec_range(spec_begin(), spec_end());
1076 }
1077
1079 return makeSpecIterator(getSpecializations(), false);
1080 }
1081
1083 return makeSpecIterator(getSpecializations(), true);
1084 }
1085
1086 /// Return whether this function template is an abbreviated function template,
1087 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1088 bool isAbbreviated() const {
1089 // Since the invented template parameters generated from 'auto' parameters
1090 // are either appended to the end of the explicit template parameter list or
1091 // form a new template parameter list, we can simply observe the last
1092 // parameter to determine if such a thing happened.
1094 return TPL->getParam(TPL->size() - 1)->isImplicit();
1095 }
1096
1097 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1099
1100 /// Create a function template node.
1103 DeclarationName Name,
1104 TemplateParameterList *Params,
1105 NamedDecl *Decl);
1106
1107 /// Create an empty function template node.
1109 GlobalDeclID ID);
1110
1111 // Implement isa/cast/dyncast support
1112 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1113 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1114};
1115
1116//===----------------------------------------------------------------------===//
1117// Kinds of Template Parameters
1118//===----------------------------------------------------------------------===//
1119
1120/// Defines the position of a template parameter within a template
1121/// parameter list.
1122///
1123/// Because template parameter can be listed
1124/// sequentially for out-of-line template members, each template parameter is
1125/// given a Depth - the nesting of template parameter scopes - and a Position -
1126/// the occurrence within the parameter list.
1127/// This class is inheritedly privately by different kinds of template
1128/// parameters and is not part of the Decl hierarchy. Just a facility.
1130protected:
1131 enum { DepthWidth = 20, PositionWidth = 12 };
1132 unsigned Depth : DepthWidth;
1134
1135 TemplateParmPosition(int D, int P) {
1136 setDepth(D);
1137 setPosition(P);
1138 }
1139
1140public:
1142
1143 /// Get the nesting depth of the template parameter.
1144 unsigned getDepth() const { return Depth; }
1145 void setDepth(int D) {
1146 assert(D >= 0 && "The depth cannot be negative");
1147 assert(D < (1 << DepthWidth) && "The depth is too large");
1148 Depth = D;
1149 }
1150
1151 /// Get the position of the template parameter within its parameter list.
1152 unsigned getPosition() const { return Position; }
1153 void setPosition(int P) {
1154 assert(P >= 0 && "The position cannot be negative");
1155 assert(P < (1 << PositionWidth) && "The position is too large");
1156 Position = P;
1157 }
1158
1159 /// Get the index of the template parameter within its parameter list.
1160 unsigned getIndex() const { return Position; }
1161};
1162
1163/// Declaration of a template type parameter.
1164///
1165/// For example, "T" in
1166/// \code
1167/// template<typename T> class vector;
1168/// \endcode
1169class TemplateTypeParmDecl final : public TypeDecl,
1170 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1171 /// Sema creates these on the stack during auto type deduction.
1172 friend class Sema;
1173 friend TrailingObjects;
1174 friend class ASTDeclReader;
1175
1176 /// Whether this template type parameter was declaration with
1177 /// the 'typename' keyword.
1178 ///
1179 /// If false, it was declared with the 'class' keyword.
1180 bool Typename : 1;
1181
1182 /// Whether this template type parameter has a type-constraint construct.
1183 bool HasTypeConstraint : 1;
1184
1185 /// Whether the type constraint has been initialized. This can be false if the
1186 /// constraint was not initialized yet or if there was an error forming the
1187 /// type constraint.
1188 bool TypeConstraintInitialized : 1;
1189
1190 /// The number of type parameters in an expanded parameter pack, if any.
1191 UnsignedOrNone NumExpanded = std::nullopt;
1192
1193 /// The default template argument, if any.
1194 using DefArgStorage =
1196 DefArgStorage DefaultArgument;
1197
1198 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1199 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1200 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1201 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1202 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1203 NumExpanded(NumExpanded) {}
1204
1205public:
1206 static TemplateTypeParmDecl *
1207 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1208 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1209 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1210 UnsignedOrNone NumExpanded = std::nullopt);
1212 GlobalDeclID ID);
1214 GlobalDeclID ID,
1215 bool HasTypeConstraint);
1216
1217 /// Whether this template type parameter was declared with
1218 /// the 'typename' keyword.
1219 ///
1220 /// If not, it was either declared with the 'class' keyword or with a
1221 /// type-constraint (see hasTypeConstraint()).
1223 return Typename && !HasTypeConstraint;
1224 }
1225
1226 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1227
1228 /// Determine whether this template parameter has a default
1229 /// argument.
1230 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1231
1232 /// Retrieve the default argument, if any.
1234 static const TemplateArgumentLoc NoneLoc;
1235 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1236 }
1237
1238 /// Retrieves the location of the default argument declaration.
1240
1241 /// Determines whether the default argument was inherited
1242 /// from a previous declaration of this template.
1244 return DefaultArgument.isInherited();
1245 }
1246
1247 /// Set the default argument for this template parameter.
1248 void setDefaultArgument(const ASTContext &C,
1249 const TemplateArgumentLoc &DefArg);
1250
1251 /// Set that this default argument was inherited from another
1252 /// parameter.
1254 TemplateTypeParmDecl *Prev) {
1255 DefaultArgument.setInherited(C, Prev);
1256 }
1257
1258 /// Removes the default argument of this template parameter.
1260 DefaultArgument.clear();
1261 }
1262
1263 /// Set whether this template type parameter was declared with
1264 /// the 'typename' or 'class' keyword.
1265 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1266
1267 /// Retrieve the depth of the template parameter.
1268 unsigned getDepth() const;
1269
1270 /// Retrieve the index of the template parameter.
1271 unsigned getIndex() const;
1272
1273 /// Returns whether this is a parameter pack.
1274 bool isParameterPack() const;
1275
1276 /// Whether this parameter pack is a pack expansion.
1277 ///
1278 /// A template type template parameter pack can be a pack expansion if its
1279 /// type-constraint contains an unexpanded parameter pack.
1280 bool isPackExpansion() const {
1281 if (!isParameterPack())
1282 return false;
1283 if (const TypeConstraint *TC = getTypeConstraint())
1284 if (TC->hasExplicitTemplateArgs())
1285 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1286 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1287 return true;
1288 return false;
1289 }
1290
1291 /// Whether this parameter is a template type parameter pack that has a known
1292 /// list of different type-constraints at different positions.
1293 ///
1294 /// A parameter pack is an expanded parameter pack when the original
1295 /// parameter pack's type-constraint was itself a pack expansion, and that
1296 /// expansion has already been expanded. For example, given:
1297 ///
1298 /// \code
1299 /// template<typename ...Types>
1300 /// struct X {
1301 /// template<convertible_to<Types> ...Convertibles>
1302 /// struct Y { /* ... */ };
1303 /// };
1304 /// \endcode
1305 ///
1306 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1307 /// its type-constraint. When \c Types is supplied with template arguments by
1308 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1309 /// expanded parameter pack. For example, instantiating
1310 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1311 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1312 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1313 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1314
1315 /// Returns the type constraint associated with this template parameter (if
1316 /// any).
1318 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1319 }
1320
1322 Expr *ImmediatelyDeclaredConstraint,
1323 UnsignedOrNone ArgPackSubstIndex);
1324
1325 /// Determine whether this template parameter has a type-constraint.
1326 bool hasTypeConstraint() const {
1327 return HasTypeConstraint;
1328 }
1329
1330 /// \brief Get the associated-constraints of this template parameter.
1331 /// This will either be the immediately-introduced constraint or empty.
1332 ///
1333 /// Use this instead of getTypeConstraint for concepts APIs that
1334 /// accept an ArrayRef of constraint expressions.
1337 if (HasTypeConstraint)
1338 AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1339 getTypeConstraint()->getArgPackSubstIndex());
1340 }
1341
1342 SourceRange getSourceRange() const override LLVM_READONLY;
1343
1344 // Implement isa/cast/dyncast/etc.
1345 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1346 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1347};
1348
1349/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1350/// e.g., "Size" in
1351/// @code
1352/// template<int Size> class array { };
1353/// @endcode
1354class NonTypeTemplateParmDecl final
1355 : public DeclaratorDecl,
1356 protected TemplateParmPosition,
1357 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1358 std::pair<QualType, TypeSourceInfo *>,
1359 Expr *> {
1360 friend class ASTDeclReader;
1361 friend TrailingObjects;
1362
1363 /// The default template argument, if any, and whether or not
1364 /// it was inherited.
1365 using DefArgStorage =
1367 DefArgStorage DefaultArgument;
1368
1369 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1370 // down here to save memory.
1371
1372 /// Whether this non-type template parameter is a parameter pack.
1373 bool ParameterPack;
1374
1375 /// Whether this non-type template parameter is an "expanded"
1376 /// parameter pack, meaning that its type is a pack expansion and we
1377 /// already know the set of types that expansion expands to.
1378 bool ExpandedParameterPack = false;
1379
1380 /// The number of types in an expanded parameter pack.
1381 unsigned NumExpandedTypes = 0;
1382
1383 size_t numTrailingObjects(
1384 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1385 return NumExpandedTypes;
1386 }
1387
1389 SourceLocation IdLoc, int D, int P,
1390 const IdentifierInfo *Id, QualType T,
1391 bool ParameterPack, TypeSourceInfo *TInfo)
1392 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1393 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1394
1395 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1396 SourceLocation IdLoc, int D, int P,
1397 const IdentifierInfo *Id, QualType T,
1398 TypeSourceInfo *TInfo,
1399 ArrayRef<QualType> ExpandedTypes,
1400 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1401
1402public:
1403 static NonTypeTemplateParmDecl *
1404 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1405 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1406 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1407
1408 static NonTypeTemplateParmDecl *
1409 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1410 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1411 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1412 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1413
1414 static NonTypeTemplateParmDecl *
1415 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1416 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1417 GlobalDeclID ID,
1418 unsigned NumExpandedTypes,
1419 bool HasTypeConstraint);
1420
1426
1427 SourceRange getSourceRange() const override LLVM_READONLY;
1428
1429 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1430
1431 /// Determine whether this template parameter has a default
1432 /// argument.
1433 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1434
1435 /// Retrieve the default argument, if any.
1437 static const TemplateArgumentLoc NoneLoc;
1438 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1439 }
1440
1441 /// Retrieve the location of the default argument, if any.
1443
1444 /// Determines whether the default argument was inherited
1445 /// from a previous declaration of this template.
1447 return DefaultArgument.isInherited();
1448 }
1449
1450 /// Set the default argument for this template parameter, and
1451 /// whether that default argument was inherited from another
1452 /// declaration.
1453 void setDefaultArgument(const ASTContext &C,
1454 const TemplateArgumentLoc &DefArg);
1456 NonTypeTemplateParmDecl *Parm) {
1457 DefaultArgument.setInherited(C, Parm);
1458 }
1459
1460 /// Removes the default argument of this template parameter.
1461 void removeDefaultArgument() { DefaultArgument.clear(); }
1462
1463 /// Whether this parameter is a non-type template parameter pack.
1464 ///
1465 /// If the parameter is a parameter pack, the type may be a
1466 /// \c PackExpansionType. In the following example, the \c Dims parameter
1467 /// is a parameter pack (whose type is 'unsigned').
1468 ///
1469 /// \code
1470 /// template<typename T, unsigned ...Dims> struct multi_array;
1471 /// \endcode
1472 bool isParameterPack() const { return ParameterPack; }
1473
1474 /// Whether this parameter pack is a pack expansion.
1475 ///
1476 /// A non-type template parameter pack is a pack expansion if its type
1477 /// contains an unexpanded parameter pack. In this case, we will have
1478 /// built a PackExpansionType wrapping the type.
1479 bool isPackExpansion() const {
1480 return ParameterPack && getType()->getAs<PackExpansionType>();
1481 }
1482
1483 /// Whether this parameter is a non-type template parameter pack
1484 /// that has a known list of different types at different positions.
1485 ///
1486 /// A parameter pack is an expanded parameter pack when the original
1487 /// parameter pack's type was itself a pack expansion, and that expansion
1488 /// has already been expanded. For example, given:
1489 ///
1490 /// \code
1491 /// template<typename ...Types>
1492 /// struct X {
1493 /// template<Types ...Values>
1494 /// struct Y { /* ... */ };
1495 /// };
1496 /// \endcode
1497 ///
1498 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1499 /// which expands \c Types. When \c Types is supplied with template arguments
1500 /// by instantiating \c X, the instantiation of \c Values becomes an
1501 /// expanded parameter pack. For example, instantiating
1502 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1503 /// pack with expansion types \c int and \c unsigned int.
1504 ///
1505 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1506 /// return the expansion types.
1507 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1508
1509 /// Retrieves the number of expansion types in an expanded parameter
1510 /// pack.
1511 unsigned getNumExpansionTypes() const {
1512 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1513 return NumExpandedTypes;
1514 }
1515
1516 /// Retrieve a particular expansion type within an expanded parameter
1517 /// pack.
1518 QualType getExpansionType(unsigned I) const {
1519 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1520 auto TypesAndInfos =
1521 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1522 return TypesAndInfos[I].first;
1523 }
1524
1525 /// Retrieve a particular expansion type source info within an
1526 /// expanded parameter pack.
1528 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1529 auto TypesAndInfos =
1530 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1531 return TypesAndInfos[I].second;
1532 }
1533
1534 /// Return the constraint introduced by the placeholder type of this non-type
1535 /// template parameter (if any).
1537 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1538 nullptr;
1539 }
1540
1542 *getTrailingObjects<Expr *>() = E;
1543 }
1544
1545 /// Determine whether this non-type template parameter's type has a
1546 /// placeholder with a type-constraint.
1548 auto *AT = getType()->getContainedAutoType();
1549 return AT && AT->isConstrained();
1550 }
1551
1552 /// \brief Get the associated-constraints of this template parameter.
1553 /// This will either be a vector of size 1 containing the immediately-declared
1554 /// constraint introduced by the placeholder type, or an empty vector.
1555 ///
1556 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1557 /// concepts APIs that accept an ArrayRef of constraint expressions.
1561 AC.emplace_back(E);
1562 }
1563
1564 // Implement isa/cast/dyncast/etc.
1565 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1566 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1567};
1568
1569/// TemplateTemplateParmDecl - Declares a template template parameter,
1570/// e.g., "T" in
1571/// @code
1572/// template <template <typename> class T> class container { };
1573/// @endcode
1574/// A template template parameter is a TemplateDecl because it defines the
1575/// name of a template and the template parameters allowable for substitution.
1576class TemplateTemplateParmDecl final
1577 : public TemplateDecl,
1578 protected TemplateParmPosition,
1579 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1580 TemplateParameterList *> {
1581 /// The default template argument, if any.
1582 using DefArgStorage =
1584 DefArgStorage DefaultArgument;
1585
1586 LLVM_PREFERRED_TYPE(TemplateNameKind)
1587 unsigned ParameterKind : 3;
1588
1589 /// Whether this template template parameter was declaration with
1590 /// the 'typename' keyword.
1591 ///
1592 /// If false, it was declared with the 'class' keyword.
1593 LLVM_PREFERRED_TYPE(bool)
1594 unsigned Typename : 1;
1595
1596 /// Whether this parameter is a parameter pack.
1597 LLVM_PREFERRED_TYPE(bool)
1598 unsigned ParameterPack : 1;
1599
1600 /// Whether this template template parameter is an "expanded"
1601 /// parameter pack, meaning that it is a pack expansion and we
1602 /// already know the set of template parameters that expansion expands to.
1603 LLVM_PREFERRED_TYPE(bool)
1604 unsigned ExpandedParameterPack : 1;
1605
1606 /// The number of parameters in an expanded parameter pack.
1607 unsigned NumExpandedParams = 0;
1608
1609 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1610 bool ParameterPack, IdentifierInfo *Id,
1611 TemplateNameKind ParameterKind, bool Typename,
1612 TemplateParameterList *Params)
1613 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1614 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1615 Typename(Typename), ParameterPack(ParameterPack),
1616 ExpandedParameterPack(false) {}
1617
1618 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1619 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1620 bool Typename, TemplateParameterList *Params,
1622
1623 void anchor() override;
1624
1625public:
1626 friend class ASTDeclReader;
1627 friend class ASTDeclWriter;
1629
1630 static TemplateTemplateParmDecl *
1631 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1632 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1633 bool Typename, TemplateParameterList *Params);
1634
1635 static TemplateTemplateParmDecl *
1636 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1637 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1638 TemplateParameterList *Params,
1640
1641 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1642 GlobalDeclID ID);
1643 static TemplateTemplateParmDecl *
1644 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1645
1651
1652 /// Whether this template template parameter was declared with
1653 /// the 'typename' keyword.
1654 bool wasDeclaredWithTypename() const { return Typename; }
1655
1656 /// Set whether this template template parameter was declared with
1657 /// the 'typename' or 'class' keyword.
1658 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1659
1660 /// Whether this template template parameter is a template
1661 /// parameter pack.
1662 ///
1663 /// \code
1664 /// template<template <class T> ...MetaFunctions> struct Apply;
1665 /// \endcode
1666 bool isParameterPack() const { return ParameterPack; }
1667
1668 /// Whether this parameter pack is a pack expansion.
1669 ///
1670 /// A template template parameter pack is a pack expansion if its template
1671 /// parameter list contains an unexpanded parameter pack.
1672 bool isPackExpansion() const {
1673 return ParameterPack &&
1675 }
1676
1677 /// Whether this parameter is a template template parameter pack that
1678 /// has a known list of different template parameter lists at different
1679 /// positions.
1680 ///
1681 /// A parameter pack is an expanded parameter pack when the original parameter
1682 /// pack's template parameter list was itself a pack expansion, and that
1683 /// expansion has already been expanded. For exampe, given:
1684 ///
1685 /// \code
1686 /// template<typename...Types> struct Outer {
1687 /// template<template<Types> class...Templates> struct Inner;
1688 /// };
1689 /// \endcode
1690 ///
1691 /// The parameter pack \c Templates is a pack expansion, which expands the
1692 /// pack \c Types. When \c Types is supplied with template arguments by
1693 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1694 /// parameter pack.
1695 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1696
1697 /// Retrieves the number of expansion template parameters in
1698 /// an expanded parameter pack.
1700 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1701 return NumExpandedParams;
1702 }
1703
1704 /// Retrieve a particular expansion type within an expanded parameter
1705 /// pack.
1707 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1708 return getTrailingObjects()[I];
1709 }
1710
1711 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1712
1713 /// Determine whether this template parameter has a default
1714 /// argument.
1715 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1716
1717 /// Retrieve the default argument, if any.
1719 static const TemplateArgumentLoc NoneLoc;
1720 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1721 }
1722
1723 /// Retrieve the location of the default argument, if any.
1725
1726 /// Determines whether the default argument was inherited
1727 /// from a previous declaration of this template.
1729 return DefaultArgument.isInherited();
1730 }
1731
1732 /// Set the default argument for this template parameter, and
1733 /// whether that default argument was inherited from another
1734 /// declaration.
1735 void setDefaultArgument(const ASTContext &C,
1736 const TemplateArgumentLoc &DefArg);
1738 TemplateTemplateParmDecl *Prev) {
1739 DefaultArgument.setInherited(C, Prev);
1740 }
1741
1742 /// Removes the default argument of this template parameter.
1743 void removeDefaultArgument() { DefaultArgument.clear(); }
1744
1745 SourceRange getSourceRange() const override LLVM_READONLY {
1749 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1750 }
1751
1753 return static_cast<TemplateNameKind>(ParameterKind);
1754 }
1755
1761
1762 // Implement isa/cast/dyncast/etc.
1763 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1764 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1765};
1766
1767/// Represents the builtin template declaration which is used to
1768/// implement __make_integer_seq and other builtin templates. It serves
1769/// no real purpose beyond existing as a place to hold template parameters.
1770class BuiltinTemplateDecl : public TemplateDecl {
1772
1773 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1775
1776 void anchor() override;
1777
1778public:
1779 // Implement isa/cast/dyncast support
1780 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1781 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1782
1783 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1784 DeclarationName Name,
1785 BuiltinTemplateKind BTK) {
1786 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1787 }
1788
1789 SourceRange getSourceRange() const override LLVM_READONLY {
1790 return {};
1791 }
1792
1794
1795 bool isPackProducingBuiltinTemplate() const;
1796};
1798
1799/// Provides information about an explicit instantiation of a variable or class
1800/// template.
1802 /// The template arguments as written..
1804
1805 /// The location of the extern keyword.
1807
1808 /// The location of the template keyword.
1810
1812};
1813
1815 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1817
1818/// Represents a class template specialization, which refers to
1819/// a class template with a given set of template arguments.
1820///
1821/// Class template specializations represent both explicit
1822/// specialization of class templates, as in the example below, and
1823/// implicit instantiations of class templates.
1824///
1825/// \code
1826/// template<typename T> class array;
1827///
1828/// template<>
1829/// class array<bool> { }; // class template specialization array<bool>
1830/// \endcode
1832 public llvm::FoldingSetNode {
1833 /// Structure that stores information about a class template
1834 /// specialization that was instantiated from a class template partial
1835 /// specialization.
1836 struct SpecializedPartialSpecialization {
1837 /// The class template partial specialization from which this
1838 /// class template specialization was instantiated.
1839 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1840
1841 /// The template argument list deduced for the class template
1842 /// partial specialization itself.
1843 const TemplateArgumentList *TemplateArgs;
1844 };
1845
1846 /// The template that this specialization specializes
1847 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1848 SpecializedTemplate;
1849
1850 /// Further info for explicit template specialization/instantiation.
1851 /// Does not apply to implicit specializations.
1852 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1853
1854 /// The template arguments used to describe this specialization.
1855 const TemplateArgumentList *TemplateArgs;
1856
1857 /// The point where this template was instantiated (if any)
1858 SourceLocation PointOfInstantiation;
1859
1860 /// The kind of specialization this declaration refers to.
1861 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1862 unsigned SpecializationKind : 3;
1863
1864 /// Indicate that we have matched a parameter pack with a non pack
1865 /// argument, when the opposite match is also allowed.
1866 /// This needs to be cached as deduction is performed during declaration,
1867 /// and we need the information to be preserved so that it is consistent
1868 /// during instantiation.
1869 LLVM_PREFERRED_TYPE(bool)
1870 unsigned StrictPackMatch : 1;
1871
1872protected:
1874 DeclContext *DC, SourceLocation StartLoc,
1875 SourceLocation IdLoc,
1876 ClassTemplateDecl *SpecializedTemplate,
1878 bool StrictPackMatch,
1880
1882
1883public:
1884 friend class ASTDeclReader;
1885 friend class ASTDeclWriter;
1886
1888 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1889 SourceLocation StartLoc, SourceLocation IdLoc,
1890 ClassTemplateDecl *SpecializedTemplate,
1891 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1894 GlobalDeclID ID);
1895
1896 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1897 bool Qualified) const override;
1898
1903
1908
1909 /// Retrieve the template that this specialization specializes.
1911
1912 /// Retrieve the template arguments of the class template
1913 /// specialization.
1915 return *TemplateArgs;
1916 }
1917
1919 TemplateArgs = Args;
1920 }
1921
1922 /// Determine the kind of specialization that this
1923 /// declaration represents.
1925 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1926 }
1927
1931
1932 /// Is this an explicit specialization at class scope (within the class that
1933 /// owns the primary template)? For example:
1934 ///
1935 /// \code
1936 /// template<typename T> struct Outer {
1937 /// template<typename U> struct Inner;
1938 /// template<> struct Inner; // class-scope explicit specialization
1939 /// };
1940 /// \endcode
1945
1946 /// True if this declaration is an explicit specialization,
1947 /// explicit instantiation declaration, or explicit instantiation
1948 /// definition.
1953
1955 SpecializedTemplate = Specialized;
1956 }
1957
1959 SpecializationKind = TSK;
1960 }
1961
1962 bool hasStrictPackMatch() const { return StrictPackMatch; }
1963
1964 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1965
1966 /// Get the point of instantiation (if any), or null if none.
1968 return PointOfInstantiation;
1969 }
1970
1972 assert(Loc.isValid() && "point of instantiation must be valid!");
1973 PointOfInstantiation = Loc;
1974 }
1975
1976 /// If this class template specialization is an instantiation of
1977 /// a template (rather than an explicit specialization), return the
1978 /// class template or class template partial specialization from which it
1979 /// was instantiated.
1980 llvm::PointerUnion<ClassTemplateDecl *,
1984 return llvm::PointerUnion<ClassTemplateDecl *,
1986
1988 }
1989
1990 /// Retrieve the class template or class template partial
1991 /// specialization which was specialized by this.
1992 llvm::PointerUnion<ClassTemplateDecl *,
1995 if (const auto *PartialSpec =
1996 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1997 return PartialSpec->PartialSpecialization;
1998
1999 return cast<ClassTemplateDecl *>(SpecializedTemplate);
2000 }
2001
2002 /// Retrieve the set of template arguments that should be used
2003 /// to instantiate members of the class template or class template partial
2004 /// specialization from which this class template specialization was
2005 /// instantiated.
2006 ///
2007 /// \returns For a class template specialization instantiated from the primary
2008 /// template, this function will return the same template arguments as
2009 /// getTemplateArgs(). For a class template specialization instantiated from
2010 /// a class template partial specialization, this function will return the
2011 /// deduced template arguments for the class template partial specialization
2012 /// itself.
2014 if (const auto *PartialSpec =
2015 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2016 return *PartialSpec->TemplateArgs;
2017
2018 return getTemplateArgs();
2019 }
2020
2021 /// Note that this class template specialization is actually an
2022 /// instantiation of the given class template partial specialization whose
2023 /// template arguments have been deduced.
2025 const TemplateArgumentList *TemplateArgs) {
2026 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2027 "Already set to a class template partial specialization!");
2028 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2029 PS->PartialSpecialization = PartialSpec;
2030 PS->TemplateArgs = TemplateArgs;
2031 SpecializedTemplate = PS;
2032 }
2033
2034 /// Note that this class template specialization is an instantiation
2035 /// of the given class template.
2037 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2038 "Previously set to a class template partial specialization!");
2039 SpecializedTemplate = TemplDecl;
2040 }
2041
2042 /// Retrieve the template argument list as written in the sources,
2043 /// if any.
2045 if (auto *Info =
2046 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2047 return Info->TemplateArgsAsWritten;
2048 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2049 }
2050
2051 /// Set the template argument list as written in the sources.
2052 void
2054 if (auto *Info =
2055 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2056 Info->TemplateArgsAsWritten = ArgsWritten;
2057 else
2058 ExplicitInfo = ArgsWritten;
2059 }
2060
2061 /// Set the template argument list as written in the sources.
2066
2067 /// Gets the location of the extern keyword, if present.
2069 if (auto *Info =
2070 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2071 return Info->ExternKeywordLoc;
2072 return SourceLocation();
2073 }
2074
2075 /// Sets the location of the extern keyword.
2077
2078 /// Gets the location of the template keyword, if present.
2080 if (auto *Info =
2081 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2082 return Info->TemplateKeywordLoc;
2083 return SourceLocation();
2084 }
2085
2086 /// Sets the location of the template keyword.
2088
2089 SourceRange getSourceRange() const override LLVM_READONLY;
2090
2091 void Profile(llvm::FoldingSetNodeID &ID) const {
2092 Profile(ID, TemplateArgs->asArray(), getASTContext());
2093 }
2094
2095 static void
2096 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2097 const ASTContext &Context) {
2098 ID.AddInteger(TemplateArgs.size());
2099 for (const TemplateArgument &TemplateArg : TemplateArgs)
2100 TemplateArg.Profile(ID, Context);
2101 }
2102
2103 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2104
2105 static bool classofKind(Kind K) {
2106 return K >= firstClassTemplateSpecialization &&
2107 K <= lastClassTemplateSpecialization;
2108 }
2109};
2110
2111class ClassTemplatePartialSpecializationDecl
2113 /// The list of template parameters
2114 TemplateParameterList *TemplateParams = nullptr;
2115
2116 /// The class template partial specialization from which this
2117 /// class template partial specialization was instantiated.
2118 ///
2119 /// The boolean value will be true to indicate that this class template
2120 /// partial specialization was specialized at this level.
2121 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2122 InstantiatedFromMember;
2123
2124 mutable CanQualType CanonInjectedTST;
2125
2126 ClassTemplatePartialSpecializationDecl(
2127 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2129 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2130 CanQualType CanonInjectedTST,
2131 ClassTemplatePartialSpecializationDecl *PrevDecl);
2132
2133 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2134 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2135 InstantiatedFromMember(nullptr, false) {}
2136
2137 void anchor() override;
2138
2139public:
2140 friend class ASTDeclReader;
2141 friend class ASTDeclWriter;
2142
2143 static ClassTemplatePartialSpecializationDecl *
2144 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2145 SourceLocation StartLoc, SourceLocation IdLoc,
2146 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2147 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2148 ClassTemplatePartialSpecializationDecl *PrevDecl);
2149
2150 static ClassTemplatePartialSpecializationDecl *
2152
2153 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2155 static_cast<ClassTemplateSpecializationDecl *>(
2156 this)->getMostRecentDecl());
2157 }
2158
2159 /// Get the list of template parameters
2161 return TemplateParams;
2162 }
2163
2164 /// \brief All associated constraints of this partial specialization,
2165 /// including the requires clause and any constraints derived from
2166 /// constrained-parameters.
2167 ///
2168 /// The constraints in the resulting list are to be treated as if in a
2169 /// conjunction ("and").
2172 TemplateParams->getAssociatedConstraints(AC);
2173 }
2174
2176 return TemplateParams->hasAssociatedConstraints();
2177 }
2178
2179 /// Retrieve the member class template partial specialization from
2180 /// which this particular class template partial specialization was
2181 /// instantiated.
2182 ///
2183 /// \code
2184 /// template<typename T>
2185 /// struct Outer {
2186 /// template<typename U> struct Inner;
2187 /// template<typename U> struct Inner<U*> { }; // #1
2188 /// };
2189 ///
2190 /// Outer<float>::Inner<int*> ii;
2191 /// \endcode
2192 ///
2193 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2194 /// end up instantiating the partial specialization
2195 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2196 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2197 /// \c Outer<float>::Inner<U*>, this function would return
2198 /// \c Outer<T>::Inner<U*>.
2199 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2200 const auto *First =
2202 return First->InstantiatedFromMember.getPointer();
2203 }
2208
2210 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2212 First->InstantiatedFromMember.setPointer(PartialSpec);
2213 }
2214
2215 /// Determines whether this class template partial specialization
2216 /// template was a specialization of a member partial specialization.
2217 ///
2218 /// In the following example, the member template partial specialization
2219 /// \c X<int>::Inner<T*> is a member specialization.
2220 ///
2221 /// \code
2222 /// template<typename T>
2223 /// struct X {
2224 /// template<typename U> struct Inner;
2225 /// template<typename U> struct Inner<U*>;
2226 /// };
2227 ///
2228 /// template<> template<typename T>
2229 /// struct X<int>::Inner<T*> { /* ... */ };
2230 /// \endcode
2232 const auto *First =
2234 return First->InstantiatedFromMember.getInt();
2235 }
2236
2237 /// Note that this member template is a specialization.
2238 /// A partial specialization may be a member specialization even if it is not
2239 /// an instantiation of a member partial specialization.
2242 return First->InstantiatedFromMember.setInt(true);
2243 }
2244
2245 /// Retrieves the canonical injected specialization type for this partial
2246 /// specialization.
2249
2250 SourceRange getSourceRange() const override LLVM_READONLY;
2251
2252 void Profile(llvm::FoldingSetNodeID &ID) const {
2254 getASTContext());
2255 }
2256
2257 static void
2258 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2259 TemplateParameterList *TPL, const ASTContext &Context);
2260
2261 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2262
2263 static bool classofKind(Kind K) {
2264 return K == ClassTemplatePartialSpecialization;
2265 }
2266};
2267
2268/// Declaration of a class template.
2270protected:
2271 /// Data that is common to all of the declarations of a given
2272 /// class template.
2274 /// The class template specializations for this class
2275 /// template, including explicit specializations and instantiations.
2276 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2277
2278 /// The class template partial specializations for this class
2279 /// template.
2280 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2282
2283 /// The Injected Template Specialization Type for this declaration.
2285
2286 Common() = default;
2287 };
2288
2289 /// Retrieve the set of specializations of this class template.
2290 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2291 getSpecializations() const;
2292
2293 /// Retrieve the set of partial specializations of this class
2294 /// template.
2295 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2297
2300 NamedDecl *Decl)
2301 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2302
2303 CommonBase *newCommon(ASTContext &C) const override;
2304
2306 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2307 }
2308
2310
2311public:
2312
2313 friend class ASTDeclReader;
2314 friend class ASTDeclWriter;
2316
2317 /// Load any lazily-loaded specializations from the external source.
2318 void LoadLazySpecializations(bool OnlyPartial = false) const;
2319
2320 /// Get the underlying class declarations of the template.
2322 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2323 }
2324
2325 /// Returns whether this template declaration defines the primary
2326 /// class pattern.
2330
2331 /// \brief Create a class template node.
2334 DeclarationName Name,
2335 TemplateParameterList *Params,
2336 NamedDecl *Decl);
2337
2338 /// Create an empty class template node.
2340
2341 /// Return the specialization with the provided arguments if it exists,
2342 /// otherwise return the insertion point.
2345 llvm::FoldingSetInsertToken &InsertToken);
2346
2347 /// Insert the specified specialization knowing that it is not already
2348 /// in. InsertToken must be obtained from findSpecialization.
2350 llvm::FoldingSetInsertToken InsertToken);
2351
2360
2361 /// Retrieve the previous declaration of this class template, or
2362 /// nullptr if no such declaration exists.
2364 return cast_or_null<ClassTemplateDecl>(
2365 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2366 }
2368 return cast_or_null<ClassTemplateDecl>(
2369 static_cast<const RedeclarableTemplateDecl *>(
2370 this)->getPreviousDecl());
2371 }
2372
2378 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2379 }
2380
2382 return cast_or_null<ClassTemplateDecl>(
2384 }
2385
2386 /// Return the partial specialization with the provided arguments if it
2387 /// exists, otherwise return the insertion point.
2391 llvm::FoldingSetInsertToken &InsertToken);
2392
2393 /// Insert the specified partial specialization knowing that it is not
2394 /// already in. InsertToken must be obtained from findPartialSpecialization.
2396 llvm::FoldingSetInsertToken InsertToken);
2397
2398 /// Retrieve the partial specializations as an ordered list.
2401
2402 /// Find a class template partial specialization with the given
2403 /// type T.
2404 ///
2405 /// \param T a dependent type that names a specialization of this class
2406 /// template.
2407 ///
2408 /// \returns the class template partial specialization that exactly matches
2409 /// the type \p T, or nullptr if no such partial specialization exists.
2411
2412 /// Find a class template partial specialization which was instantiated
2413 /// from the given member partial specialization.
2414 ///
2415 /// \param D a member class template partial specialization.
2416 ///
2417 /// \returns the class template partial specialization which was instantiated
2418 /// from the given member partial specialization, or nullptr if no such
2419 /// partial specialization exists.
2423
2424 /// Retrieve the canonical template specialization type of the
2425 /// injected-class-name for this class template.
2426 ///
2427 /// The injected-class-name for a class template \c X is \c
2428 /// X<template-args>, where \c template-args is formed from the
2429 /// template arguments that correspond to the template parameters of
2430 /// \c X. For example:
2431 ///
2432 /// \code
2433 /// template<typename T, int N>
2434 /// struct array {
2435 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2436 /// };
2437 /// \endcode
2440
2442 using spec_range = llvm::iterator_range<spec_iterator>;
2443
2445 return spec_range(spec_begin(), spec_end());
2446 }
2447
2449 return makeSpecIterator(getSpecializations(), false);
2450 }
2451
2453 return makeSpecIterator(getSpecializations(), true);
2454 }
2455
2456 // Implement isa/cast/dyncast support
2457 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2458 static bool classofKind(Kind K) { return K == ClassTemplate; }
2459};
2460
2461/// Declaration of a friend template.
2462///
2463/// For example:
2464/// \code
2465/// template <typename T> class A {
2466/// friend class MyVector<T>; // not a friend template
2467/// template <typename U> friend class B; // friend class template
2468/// template <typename U> friend class Foo<T>::Nested; // friend template
2469/// };
2470/// \endcode
2471class FriendTemplateDecl final
2472 : public FriendDecl,
2473 private llvm::TrailingObjects<FriendTemplateDecl,
2474 TemplateParameterList *> {
2475 void anchor() override;
2476
2477private:
2478 unsigned NumTPLists = 0;
2479 TemplateName Template;
2480
2481 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, FriendUnion Friend,
2482 SourceLocation FriendLoc, SourceLocation EllipsisLoc,
2484 TemplateName Template = {})
2485 : FriendDecl(Decl::FriendTemplate, DC, Loc, Friend, FriendLoc,
2486 EllipsisLoc),
2487 NumTPLists(FriendTPLists.size()), Template(Template) {
2488 assert(!FriendTPLists.empty());
2489 llvm::copy(FriendTPLists, getTrailingObjects());
2490 }
2491
2492 FriendTemplateDecl(EmptyShell Empty, unsigned NumFriendTPLists)
2493 : FriendDecl(Decl::FriendTemplate, Empty), NumTPLists(NumFriendTPLists) {
2494 assert(NumFriendTPLists != 0);
2495 }
2496
2497public:
2498 friend class ASTDeclReader;
2499 friend class ASTDeclWriter;
2501
2502 enum class FriendTemplateEntityKind { Type, Template, Decl };
2503
2504 static FriendTemplateDecl *
2505 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2508 SourceLocation EllipsisLoc = {}, TemplateName Template = {});
2509
2510 static FriendTemplateDecl *
2511 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2512 TemplateName Template, SourceLocation FriendLoc,
2513 ArrayRef<TemplateParameterList *> FriendTPLists,
2514 SourceLocation EllipsisLoc = {});
2515
2516 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
2517 unsigned NumFriendTPLists);
2518
2519 SourceRange getSourceRange() const override LLVM_READONLY;
2520
2521 TemplateName getFriendTemplateName() const { return Template; }
2522
2524 if (getFriendType())
2526 if (Template.isNull())
2529 }
2530
2531 NamedDecl *getFriendDecl() const override {
2532 if (NamedDecl *ND = Friend.dyn_cast<NamedDecl *>())
2533 return ND;
2534 return Template.getAsTemplateDecl();
2535 }
2536
2538 return ArrayRef(getTrailingObjects(), NumTPLists);
2539 }
2540
2541 // Implement isa/cast/dyncast/etc.
2542 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2543 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2544};
2545
2546/// Declaration of an alias template.
2547///
2548/// For example:
2549/// \code
2550/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2551/// \endcode
2553protected:
2555
2561
2562 CommonBase *newCommon(ASTContext &C) const override;
2563
2565 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2566 }
2567
2568public:
2569 friend class ASTDeclReader;
2570 friend class ASTDeclWriter;
2571
2572 /// Get the underlying function declaration of the template.
2574 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2575 }
2576
2577
2586
2587 /// Retrieve the previous declaration of this function template, or
2588 /// nullptr if no such declaration exists.
2590 return cast_or_null<TypeAliasTemplateDecl>(
2591 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2592 }
2594 return cast_or_null<TypeAliasTemplateDecl>(
2595 static_cast<const RedeclarableTemplateDecl *>(
2596 this)->getPreviousDecl());
2597 }
2598
2600 return cast_or_null<TypeAliasTemplateDecl>(
2602 }
2603
2604 /// Create a function template node.
2607 DeclarationName Name,
2608 TemplateParameterList *Params,
2609 NamedDecl *Decl);
2610
2611 /// Create an empty alias template node.
2613 GlobalDeclID ID);
2614
2615 // Implement isa/cast/dyncast support
2616 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2617 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2618};
2619
2620/// Represents a variable template specialization, which refers to
2621/// a variable template with a given set of template arguments.
2622///
2623/// Variable template specializations represent both explicit
2624/// specializations of variable templates, as in the example below, and
2625/// implicit instantiations of variable templates.
2626///
2627/// \code
2628/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2629///
2630/// template<>
2631/// constexpr float pi<float>; // variable template specialization pi<float>
2632/// \endcode
2634 public llvm::FoldingSetNode {
2635
2636 /// Structure that stores information about a variable template
2637 /// specialization that was instantiated from a variable template partial
2638 /// specialization.
2639 struct SpecializedPartialSpecialization {
2640 /// The variable template partial specialization from which this
2641 /// variable template specialization was instantiated.
2642 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2643
2644 /// The template argument list deduced for the variable template
2645 /// partial specialization itself.
2646 const TemplateArgumentList *TemplateArgs;
2647 };
2648
2649 /// The template that this specialization specializes.
2650 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2651 SpecializedTemplate;
2652
2653 /// Further info for explicit template specialization/instantiation.
2654 /// Does not apply to implicit specializations.
2655 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2656
2657 /// The template arguments used to describe this specialization.
2658 const TemplateArgumentList *TemplateArgs;
2659
2660 /// The point where this template was instantiated (if any).
2661 SourceLocation PointOfInstantiation;
2662
2663 /// The kind of specialization this declaration refers to.
2664 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2665 unsigned SpecializationKind : 3;
2666
2667 /// Whether this declaration is a complete definition of the
2668 /// variable template specialization. We can't otherwise tell apart
2669 /// an instantiated declaration from an instantiated definition with
2670 /// no initializer.
2671 LLVM_PREFERRED_TYPE(bool)
2672 unsigned IsCompleteDefinition : 1;
2673
2674protected:
2676 SourceLocation StartLoc, SourceLocation IdLoc,
2677 VarTemplateDecl *SpecializedTemplate,
2678 QualType T, TypeSourceInfo *TInfo,
2679 StorageClass S,
2681
2682 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2683
2684public:
2685 friend class ASTDeclReader;
2686 friend class ASTDeclWriter;
2687 friend class VarDecl;
2688
2690 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2691 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2692 TypeSourceInfo *TInfo, StorageClass S,
2695 GlobalDeclID ID);
2696
2697 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2698 bool Qualified) const override;
2699
2701 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2703 }
2704
2705 /// Retrieve the template that this specialization specializes.
2707
2708 /// Retrieve the template arguments of the variable template
2709 /// specialization.
2710 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2711
2712 /// Determine the kind of specialization that this
2713 /// declaration represents.
2715 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2716 }
2717
2721
2726
2727 /// True if this declaration is an explicit specialization,
2728 /// explicit instantiation declaration, or explicit instantiation
2729 /// definition.
2734
2736 SpecializationKind = TSK;
2737 }
2738
2739 /// Get the point of instantiation (if any), or null if none.
2741 return PointOfInstantiation;
2742 }
2743
2745 assert(Loc.isValid() && "point of instantiation must be valid!");
2746 PointOfInstantiation = Loc;
2747 }
2748
2749 void setCompleteDefinition() { IsCompleteDefinition = true; }
2750
2751 /// If this variable template specialization is an instantiation of
2752 /// a template (rather than an explicit specialization), return the
2753 /// variable template or variable template partial specialization from which
2754 /// it was instantiated.
2755 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2758 return llvm::PointerUnion<VarTemplateDecl *,
2760
2762 }
2763
2764 /// Retrieve the variable template or variable template partial
2765 /// specialization which was specialized by this.
2766 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2768 if (const auto *PartialSpec =
2769 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2770 return PartialSpec->PartialSpecialization;
2771
2772 return cast<VarTemplateDecl *>(SpecializedTemplate);
2773 }
2774
2775 /// Retrieve the set of template arguments that should be used
2776 /// to instantiate the initializer of the variable template or variable
2777 /// template partial specialization from which this variable template
2778 /// specialization was instantiated.
2779 ///
2780 /// \returns For a variable template specialization instantiated from the
2781 /// primary template, this function will return the same template arguments
2782 /// as getTemplateArgs(). For a variable template specialization instantiated
2783 /// from a variable template partial specialization, this function will the
2784 /// return deduced template arguments for the variable template partial
2785 /// specialization itself.
2787 if (const auto *PartialSpec =
2788 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2789 return *PartialSpec->TemplateArgs;
2790
2791 return getTemplateArgs();
2792 }
2793
2794 /// Note that this variable template specialization is actually an
2795 /// instantiation of the given variable template partial specialization whose
2796 /// template arguments have been deduced.
2798 const TemplateArgumentList *TemplateArgs) {
2799 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2800 "Already set to a variable template partial specialization!");
2801 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2802 PS->PartialSpecialization = PartialSpec;
2803 PS->TemplateArgs = TemplateArgs;
2804 SpecializedTemplate = PS;
2805 }
2806
2807 /// Note that this variable template specialization is an instantiation
2808 /// of the given variable template.
2810 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2811 "Previously set to a variable template partial specialization!");
2812 SpecializedTemplate = TemplDecl;
2813 }
2814
2815 /// Retrieve the template argument list as written in the sources,
2816 /// if any.
2818 if (auto *Info =
2819 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2820 return Info->TemplateArgsAsWritten;
2821 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2822 }
2823
2824 /// Set the template argument list as written in the sources.
2825 void
2827 if (auto *Info =
2828 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2829 Info->TemplateArgsAsWritten = ArgsWritten;
2830 else
2831 ExplicitInfo = ArgsWritten;
2832 }
2833
2834 /// Set the template argument list as written in the sources.
2839
2840 /// Gets the location of the extern keyword, if present.
2842 if (auto *Info =
2843 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2844 return Info->ExternKeywordLoc;
2845 return SourceLocation();
2846 }
2847
2848 /// Sets the location of the extern keyword.
2850
2851 /// Gets the location of the template keyword, if present.
2853 if (auto *Info =
2854 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2855 return Info->TemplateKeywordLoc;
2856 return SourceLocation();
2857 }
2858
2859 /// Sets the location of the template keyword.
2861
2862 SourceRange getSourceRange() const override LLVM_READONLY;
2863
2864 void Profile(llvm::FoldingSetNodeID &ID) const {
2865 Profile(ID, TemplateArgs->asArray(), getASTContext());
2866 }
2867
2868 static void Profile(llvm::FoldingSetNodeID &ID,
2869 ArrayRef<TemplateArgument> TemplateArgs,
2870 const ASTContext &Context) {
2871 ID.AddInteger(TemplateArgs.size());
2872 for (const TemplateArgument &TemplateArg : TemplateArgs)
2873 TemplateArg.Profile(ID, Context);
2874 }
2875
2876 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2877
2878 static bool classofKind(Kind K) {
2879 return K >= firstVarTemplateSpecialization &&
2880 K <= lastVarTemplateSpecialization;
2881 }
2882};
2883
2884class VarTemplatePartialSpecializationDecl
2886 /// The list of template parameters
2887 TemplateParameterList *TemplateParams = nullptr;
2888
2889 /// The variable template partial specialization from which this
2890 /// variable template partial specialization was instantiated.
2891 ///
2892 /// The boolean value will be true to indicate that this variable template
2893 /// partial specialization was specialized at this level.
2894 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2895 InstantiatedFromMember;
2896
2897 VarTemplatePartialSpecializationDecl(
2898 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2900 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2902
2903 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2904 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2905 Context),
2906 InstantiatedFromMember(nullptr, false) {}
2907
2908 void anchor() override;
2909
2910public:
2911 friend class ASTDeclReader;
2912 friend class ASTDeclWriter;
2913
2914 static VarTemplatePartialSpecializationDecl *
2915 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2917 VarTemplateDecl *SpecializedTemplate, QualType T,
2918 TypeSourceInfo *TInfo, StorageClass S,
2920
2921 static VarTemplatePartialSpecializationDecl *
2923
2924 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2926 static_cast<VarTemplateSpecializationDecl *>(
2927 this)->getMostRecentDecl());
2928 }
2929
2930 /// Get the list of template parameters
2932 return TemplateParams;
2933 }
2934
2935 /// Get the template argument list of the template parameter list.
2937 getInjectedTemplateArgs(const ASTContext &Context) const {
2939 }
2940
2941 /// \brief All associated constraints of this partial specialization,
2942 /// including the requires clause and any constraints derived from
2943 /// constrained-parameters.
2944 ///
2945 /// The constraints in the resulting list are to be treated as if in a
2946 /// conjunction ("and").
2949 TemplateParams->getAssociatedConstraints(AC);
2950 }
2951
2953 return TemplateParams->hasAssociatedConstraints();
2954 }
2955
2956 /// \brief Retrieve the member variable template partial specialization from
2957 /// which this particular variable template partial specialization was
2958 /// instantiated.
2959 ///
2960 /// \code
2961 /// template<typename T>
2962 /// struct Outer {
2963 /// template<typename U> U Inner;
2964 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2965 /// };
2966 ///
2967 /// template int* Outer<float>::Inner<int*>;
2968 /// \endcode
2969 ///
2970 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2971 /// end up instantiating the partial specialization
2972 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2973 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2974 /// \c Outer<float>::Inner<U*>, this function would return
2975 /// \c Outer<T>::Inner<U*>.
2976 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2977 const auto *First =
2979 return First->InstantiatedFromMember.getPointer();
2980 }
2981
2982 void
2983 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2985 First->InstantiatedFromMember.setPointer(PartialSpec);
2986 }
2987
2988 /// Determines whether this variable template partial specialization
2989 /// was a specialization of a member partial specialization.
2990 ///
2991 /// In the following example, the member template partial specialization
2992 /// \c X<int>::Inner<T*> is a member specialization.
2993 ///
2994 /// \code
2995 /// template<typename T>
2996 /// struct X {
2997 /// template<typename U> U Inner;
2998 /// template<typename U> U* Inner<U*> = (U*)(0);
2999 /// };
3000 ///
3001 /// template<> template<typename T>
3002 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
3003 /// \endcode
3005 const auto *First =
3007 return First->InstantiatedFromMember.getInt();
3008 }
3009
3010 /// Note that this member template is a specialization.
3011 /// A partial specialization may be a member specialization even if it is not
3012 /// an instantiation of a member partial specialization.
3015 return First->InstantiatedFromMember.setInt(true);
3016 }
3017
3018 SourceRange getSourceRange() const override LLVM_READONLY;
3019
3020 void Profile(llvm::FoldingSetNodeID &ID) const {
3022 getASTContext());
3023 }
3024
3025 static void
3026 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3027 TemplateParameterList *TPL, const ASTContext &Context);
3028
3029 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3030
3031 static bool classofKind(Kind K) {
3032 return K == VarTemplatePartialSpecialization;
3033 }
3034};
3035
3036/// Declaration of a variable template.
3038protected:
3039 /// Data that is common to all of the declarations of a given
3040 /// variable template.
3042 /// The variable template specializations for this variable
3043 /// template, including explicit specializations and instantiations.
3044 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3045
3046 /// The variable template partial specializations for this variable
3047 /// template.
3048 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3050
3051 Common() = default;
3052 };
3053
3054 /// Retrieve the set of specializations of this variable template.
3055 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3056 getSpecializations() const;
3057
3058 /// Retrieve the set of partial specializations of this class
3059 /// template.
3060 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3062
3067
3068 CommonBase *newCommon(ASTContext &C) const override;
3069
3071 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3072 }
3073
3074public:
3075 friend class ASTDeclReader;
3076 friend class ASTDeclWriter;
3077
3078 /// Load any lazily-loaded specializations from the external source.
3079 void LoadLazySpecializations(bool OnlyPartial = false) const;
3080
3081 /// Get the underlying variable declarations of the template.
3083 return static_cast<VarDecl *>(TemplatedDecl);
3084 }
3085
3086 /// Returns whether this template declaration defines the primary
3087 /// variable pattern.
3091
3093
3094 /// Create a variable template node.
3097 TemplateParameterList *Params,
3098 VarDecl *Decl);
3099
3100 /// Create an empty variable template node.
3102
3103 /// Return the specialization with the provided arguments if it exists,
3104 /// otherwise return the insertion point.
3107 llvm::FoldingSetInsertToken &InsertToken);
3108
3109 /// Insert the specified specialization knowing that it is not already
3110 /// in. InsertToken must be obtained from findSpecialization.
3112 llvm::FoldingSetInsertToken InsertToken);
3113
3120
3121 /// Retrieve the previous declaration of this variable template, or
3122 /// nullptr if no such declaration exists.
3124 return cast_or_null<VarTemplateDecl>(
3125 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3126 }
3128 return cast_or_null<VarTemplateDecl>(
3129 static_cast<const RedeclarableTemplateDecl *>(
3130 this)->getPreviousDecl());
3131 }
3132
3138 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3139 }
3140
3145
3146 /// Return the partial specialization with the provided arguments if it
3147 /// exists, otherwise return the insertion point.
3151 llvm::FoldingSetInsertToken &InsertToken);
3152
3153 /// Insert the specified partial specialization knowing that it is not
3154 /// already in. InsertToken must be obtained from findPartialSpecialization.
3156 llvm::FoldingSetInsertToken InsertToken);
3157
3158 /// Retrieve the partial specializations as an ordered list.
3161
3162 /// Find a variable template partial specialization which was
3163 /// instantiated
3164 /// from the given member partial specialization.
3165 ///
3166 /// \param D a member variable template partial specialization.
3167 ///
3168 /// \returns the variable template partial specialization which was
3169 /// instantiated
3170 /// from the given member partial specialization, or nullptr if no such
3171 /// partial specialization exists.
3174
3176 using spec_range = llvm::iterator_range<spec_iterator>;
3177
3179 return spec_range(spec_begin(), spec_end());
3180 }
3181
3183 return makeSpecIterator(getSpecializations(), false);
3184 }
3185
3187 return makeSpecIterator(getSpecializations(), true);
3188 }
3189
3190 // Implement isa/cast/dyncast support
3191 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3192 static bool classofKind(Kind K) { return K == VarTemplate; }
3193};
3194
3195/// Declaration of a C++20 concept.
3196class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3197protected:
3199
3204public:
3206 DeclarationName Name,
3207 TemplateParameterList *Params,
3208 Expr *ConstraintExpr = nullptr);
3210
3212 return ConstraintExpr;
3213 }
3214
3215 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3216
3218
3219 SourceRange getSourceRange() const override LLVM_READONLY {
3220 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3221 ConstraintExpr ? ConstraintExpr->getEndLoc()
3222 : SourceLocation());
3223 }
3224
3225 bool isTypeConcept() const {
3226 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3227 }
3228
3231 }
3233 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3234 }
3235
3236 // Implement isa/cast/dyncast/etc.
3237 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3238 static bool classofKind(Kind K) { return K == Concept; }
3239
3240 friend class ASTReader;
3241 friend class ASTDeclReader;
3242 friend class ASTDeclWriter;
3243};
3244
3245// An implementation detail of ConceptSpecialicationExpr that holds the template
3246// arguments, so we can later use this to reconstitute the template arguments
3247// during constraint checking.
3248class ImplicitConceptSpecializationDecl final
3249 : public Decl,
3250 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3251 TemplateArgument> {
3252 unsigned NumTemplateArgs;
3253
3254 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3255 ArrayRef<TemplateArgument> ConvertedArgs);
3256 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3257
3258public:
3259 static ImplicitConceptSpecializationDecl *
3261 ArrayRef<TemplateArgument> ConvertedArgs);
3262 static ImplicitConceptSpecializationDecl *
3264 unsigned NumTemplateArgs);
3265
3267 return getTrailingObjects(NumTemplateArgs);
3268 }
3270
3271 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3272 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3273
3275 friend class ASTDeclReader;
3276};
3277
3278/// A template parameter object.
3279///
3280/// Template parameter objects represent values of class type used as template
3281/// arguments. There is one template parameter object for each such distinct
3282/// value used as a template argument across the program.
3283///
3284/// \code
3285/// struct A { int x, y; };
3286/// template<A> struct S;
3287/// S<A{1, 2}> s1;
3288/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3289/// \endcode
3290class TemplateParamObjectDecl : public ValueDecl,
3291 public Mergeable<TemplateParamObjectDecl>,
3292 public llvm::FoldingSetNode {
3293private:
3294 /// The value of this template parameter object.
3295 APValue Value;
3296
3297 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3298 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3299 T),
3300 Value(V) {}
3301
3302 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3303 const APValue &V);
3304 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3305 GlobalDeclID ID);
3306
3307 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3308 /// create these.
3309 friend class ASTContext;
3310 friend class ASTReader;
3311 friend class ASTDeclReader;
3312
3313public:
3314 /// Print this template parameter object in a human-readable format.
3315 void printName(llvm::raw_ostream &OS,
3316 const PrintingPolicy &Policy) const override;
3317
3318 /// Print this object as an equivalent expression.
3319 void printAsExpr(llvm::raw_ostream &OS) const;
3320 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3321
3322 /// Print this object as an initializer suitable for a variable of the
3323 /// object's type.
3324 void printAsInit(llvm::raw_ostream &OS) const;
3325 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3326
3327 const APValue &getValue() const { return Value; }
3328
3329 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3330 const APValue &V) {
3331 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3332 V.Profile(ID);
3333 }
3334 void Profile(llvm::FoldingSetNodeID &ID) {
3335 Profile(ID, getType(), getValue());
3336 }
3337
3338 TemplateParamObjectDecl *getCanonicalDecl() override {
3339 return getFirstDecl();
3340 }
3341 const TemplateParamObjectDecl *getCanonicalDecl() const {
3342 return getFirstDecl();
3343 }
3344
3345 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3346 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3347};
3348
3349/// Represents a C++26 expansion statement declaration.
3350///
3351/// This is a bit of a hack, since expansion statements shouldn't really be
3352/// 'declarations' per se (they don't declare anything). Nevertheless, we *do*
3353/// need them to be declaration *contexts*, because the DeclContext is used to
3354/// compute the 'template depth' of entities enclosed therein. In particular,
3355/// the 'template depth' is used to find instantiations of parameter variables.
3356/// A lambda enclosed within an expansion statement cannot compute its
3357/// template depth without a pointer to the enclosing expansion statement.
3358///
3359/// For the remainder of this comment, let 'expanding' an expansion statement
3360/// refer to the process of performing template substitution on its body N
3361/// times, where N is the expansion size (how this size is determined depends on
3362/// the kind of expansion statement); by contrast we may sometimes 'instantiate'
3363/// an expansion statement (because it happens to be in a template). This is
3364/// just regular template instantiation.
3365///
3366/// This node contains a 'CXXExpansionStmtPattern' as well as a
3367/// 'CXXExpansionStmtInstantiation'. These two members correspond to
3368/// distinct representations of the expansion statement: the former is used
3369/// prior to expansion and contains all the parts needed to perform expansion;
3370/// the latter holds the expanded/desugared AST nodes that result from the
3371/// expansion.
3372///
3373/// Additionally, there is a 'NonTypeTemplateParmDecl', which is a template
3374/// parameter that serves as the expansion index, e.g. during the N-th
3375/// expansion, it is set to 'N'. See the documentation of
3376/// 'CXXExpansionStmtPattern', for more information on how this is used.
3377///
3378/// After expansion, the 'CXXExpansionStmtPattern' is no longer updated and left
3379/// as-is; this also means that, if an already-expanded expansion statement is
3380/// inside a template, and that template is then instantiated, the
3381/// 'CXXExpansionStmtPattern' is *not* instantiated; only the
3382/// 'CXXExpansionStmtInstantiation' is. The latter is also what's used for
3383/// codegen and constant evaluation.
3384///
3385/// There are different kinds of expansion statements; see the comment on
3386/// 'CXXExpansionStmtPattern' for more information.
3387///
3388/// As an example, if the user writes the following expansion statement:
3389/// \verbatim
3390/// std::tuple<int, int, int> a{1, 2, 3};
3391/// template for (auto x : a) {
3392/// // ...
3393/// }
3394/// \endverbatim
3395///
3396/// The 'CXXExpansionStmtPattern' of this particular 'CXXExpansionStmtDecl'
3397/// stores, amongst other things, the declaration of the variable 'x' as well
3398/// as the expansion-initializer 'a'.
3399///
3400/// After expansion, we end up with a 'CXXExpansionStmtInstantiation' that
3401/// is *equivalent* to the AST shown below. Note that only the inner '{}' (i.e.
3402/// those marked as 'Actual "CompoundStmt"' below) are actually present as
3403/// 'CompoundStmt's in the AST; the outer braces that wrap everything do *not*
3404/// correspond to an actual 'CompoundStmt' and are implicit in the sense that we
3405/// simply push a scope when evaluating or emitting IR for a
3406/// 'CXXExpansionStmtInstantiation'.
3407///
3408/// \verbatim
3409/// { // Not actually present in the AST.
3410/// auto [__u0, __u1, __u2] = a;
3411/// { // Actual 'CompoundStmt'.
3412/// auto x = __u0;
3413/// // ...
3414/// }
3415/// { // Actual 'CompoundStmt'.
3416/// auto x = __u1;
3417/// // ...
3418/// }
3419/// { // Actual 'CompoundStmt'.
3420/// auto x = __u2;
3421/// // ...
3422/// }
3423/// }
3424/// \endverbatim
3425///
3426/// See the documentation around 'CXXExpansionStmtInstantiation' for more notes
3427/// as to why this node exist and how it is used.
3428///
3429/// \see CXXExpansionStmtPattern
3430/// \see CXXExpansionStmtInstantiation
3431class CXXExpansionStmtDecl : public Decl, public DeclContext {
3432 CXXExpansionStmtPattern *Pattern = nullptr;
3433 NonTypeTemplateParmDecl *IndexNTTP = nullptr;
3434 CXXExpansionStmtInstantiation *Instantiations = nullptr;
3435
3436 CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
3438
3439public:
3440 friend class ASTDeclReader;
3441
3442 static CXXExpansionStmtDecl *Create(ASTContext &C, DeclContext *DC,
3443 SourceLocation Loc,
3445 static CXXExpansionStmtDecl *CreateDeserialized(ASTContext &C,
3446 GlobalDeclID ID);
3447
3449 const CXXExpansionStmtPattern *getExpansionPattern() const { return Pattern; }
3451
3454 return Instantiations;
3455 }
3456
3458 Instantiations = S;
3459 }
3460
3463 return IndexNTTP;
3464 }
3465
3466 SourceRange getSourceRange() const override LLVM_READONLY;
3467
3468 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3469 static bool classofKind(Kind K) { return K == CXXExpansionStmt; }
3470};
3471
3473 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3474 return PD;
3475 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3476 return PD;
3478}
3479
3481 auto *TD = dyn_cast<TemplateDecl>(D);
3482 return TD && (isa<ClassTemplateDecl>(TD) ||
3485 [&]() {
3486 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
3487 return TTP->templateParameterKind() == TNK_Type_template;
3488 return false;
3489 }())
3490 ? TD
3491 : nullptr;
3492}
3493
3494/// Check whether the template parameter is a pack expansion, and if so,
3495/// determine the number of parameters produced by that expansion. For instance:
3496///
3497/// \code
3498/// template<typename ...Ts> struct A {
3499/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3500/// };
3501/// \endcode
3502///
3503/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3504/// is not a pack expansion, so returns an empty Optional.
3506 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3507 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3508 return Num;
3509 }
3510
3511 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3512 if (NTTP->isExpandedParameterPack())
3513 return NTTP->getNumExpansionTypes();
3514 }
3515
3516 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3517 if (TTP->isExpandedParameterPack())
3518 return TTP->getNumExpansionTemplateParameters();
3519 }
3520
3521 return std::nullopt;
3522}
3523
3524/// Internal helper used by Subst* nodes to retrieve a parameter from the
3525/// AssociatedDecl, and the template argument substituted into it, if any.
3526std::tuple<NamedDecl *, TemplateArgument>
3527getReplacedTemplateParameter(Decl *D, unsigned Index);
3528
3529/// If we have a 'templated' declaration for a template, adjust 'D' to
3530/// refer to the actual template.
3531/// If we have an implicit instantiation, adjust 'D' to refer to template.
3532const Decl &adjustDeclToTemplate(const Decl &D);
3533
3534/// Represents an explicit instantiation of a template entity in source code.
3535///
3536/// \code
3537/// template void ns::foo<int>(int); // function template
3538/// extern template struct ns::S<int>; // class template (extern)
3539/// template int ns::bar<int>; // variable template
3540/// template void ns::S<int>::method(int); // member function
3541/// \endcode
3542class ExplicitInstantiationDecl final
3543 : public Decl,
3544 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3545 NestedNameSpecifierLoc,
3546 const ASTTemplateArgumentListInfo *> {
3547 friend class ASTDeclReader;
3548 friend class ASTDeclWriter;
3549 friend TrailingObjects;
3550
3551 /// The underlying specialization (low 3 bits: TSK).
3552 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3553
3554 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3555 /// Always non-null after construction.
3556 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3557 /// qualifier, template-name, and argument locations.
3558 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3559 /// - Function / variable templates: the declared type.
3560 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3561
3562 /// Location of the 'extern' keyword (invalid if not extern template).
3563 SourceLocation ExternLoc;
3564
3565 /// Location of the entity name (e.g., 'foo' in 'template void
3566 /// ns::foo<int>(int)').
3567 SourceLocation NameLoc;
3568
3569 enum TrailingFlags : unsigned {
3570 HasQualifierFlag = 1,
3571 HasArgsAsWrittenFlag = 2,
3572 };
3573
3574 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3575 return hasTrailingQualifier() ? 1 : 0;
3576 }
3577
3578 /// For class templates / nested classes, returns the TypeLoc encoding the
3579 /// entity (TemplateSpecializationTypeLoc or TagTypeLoc). For function /
3580 /// variable templates -- where TypeSourceInfo holds the declared type
3581 /// rather than the entity -- returns std::nullopt.
3582 std::optional<TypeLoc> getClassTypeLoc() const {
3584 return std::nullopt;
3585 if (auto *TSI = TypeAndFlags.getPointer())
3586 return TSI->getTypeLoc();
3587 return std::nullopt;
3588 }
3589
3590 /// Raw TypeSourceInfo pointer, needed by the serializer.
3591 TypeSourceInfo *getRawTypeSourceInfo() const {
3592 return TypeAndFlags.getPointer();
3593 }
3594
3595 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3596 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3598 return nullptr;
3599 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3600 }
3601
3602 ExplicitInstantiationDecl(
3603 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3604 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3605 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3606 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3607
3608 ExplicitInstantiationDecl(EmptyShell Empty)
3610
3611public:
3612 static ExplicitInstantiationDecl *
3613 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3614 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3615 NestedNameSpecifierLoc QualifierLoc,
3616 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3617 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3619
3620 static ExplicitInstantiationDecl *
3621 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3622
3623 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3624
3625 SourceRange getSourceRange() const override LLVM_READONLY;
3626 SourceLocation getEndLoc() const LLVM_READONLY;
3627
3628 SourceLocation getExternLoc() const { return ExternLoc; }
3630 SourceLocation getNameLoc() const { return NameLoc; }
3631
3632 /// The tag keyword (struct/class/union) location for class templates /
3633 /// nested classes; invalid for function / variable templates.
3635
3637 return TypeAndFlags.getInt() & HasQualifierFlag;
3638 }
3640 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3641 }
3642
3643 /// Returns the qualifier regardless of where it is stored.
3644 /// For class templates / nested classes, extracted from the class TypeLoc;
3645 /// for function / variable templates, from a trailing object.
3647
3648 /// Returns the number of explicit template arguments, or std::nullopt if
3649 /// this entity has no template argument list (e.g., nested classes).
3650 std::optional<unsigned> getNumTemplateArgs() const;
3651 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3654
3655 /// The declared type (return type or variable type) for function / variable
3656 /// templates. Null for class templates and nested classes.
3658
3660 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3661 }
3662
3663 bool isExternTemplate() const { return ExternLoc.isValid(); }
3664
3665 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3666 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3667};
3668
3669} // namespace clang
3670
3671#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:498
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:239
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:239
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
static bool classofKind(Kind K)
const NonTypeTemplateParmDecl * getIndexTemplateParm() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
CXXExpansionStmtPattern * getExpansionPattern()
static CXXExpansionStmtDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
CXXExpansionStmtInstantiation * getInstantiations()
static bool classof(const Decl *D)
const CXXExpansionStmtInstantiation * getInstantiations() const
void setInstantiations(CXXExpansionStmtInstantiation *S)
const CXXExpansionStmtPattern * getExpansionPattern() const
NonTypeTemplateParmDecl * getIndexTemplateParm()
void setExpansionPattern(CXXExpansionStmtPattern *S)
Represents the code generated for an expanded expansion statement.
Definition StmtCXX.h:1028
CXXExpansionStmtPattern - Represents an unexpanded C++ expansion statement.
Definition StmtCXX.h:675
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:2062
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:125
CXXRecordDecl * getDefinitionOrSelf() const
Definition DeclCXX.h:555
friend class DeclContext
Definition DeclCXX.h:266
Declaration of a class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
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.
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)
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
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, llvm::FoldingSetInsertToken InsertToken)
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
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
friend class TemplateDeclInstantiator
Common * getCommonPtr() const
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:1466
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
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:1012
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:1008
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:1016
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:935
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:781
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL)
Definition Decl.h:801
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
The declared type (return type or variable type) for function / variable templates.
TemplateSpecializationKind getTemplateSpecializationKind() const
SourceLocation getExternLoc() const
SourceLocation getTemplateArgsLAngleLoc() const
std::optional< unsigned > getNumTemplateArgs() const
Returns the number of explicit template arguments, or std::nullopt if this entity has no template arg...
TemplateArgumentLoc getTemplateArg(unsigned I) const
SourceLocation getTemplateArgsRAngleLoc() const
NamedDecl * getSpecialization() const
SourceLocation getTagKWLoc() const
The tag keyword (struct/class/union) location for class templates / nested classes; invalid for funct...
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:113
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
FriendDecl(Kind K, DeclContext *DC, SourceLocation L, FriendUnion Friend, SourceLocation FL, SourceLocation EllipsisLoc={})
Definition DeclFriend.h:67
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
Definition DeclFriend.h:50
FriendUnion Friend
Definition DeclFriend.h:63
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
Declaration of a friend template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static bool classof(const Decl *D)
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumFriendTPLists)
NamedDecl * getFriendDecl() const override
If this friend declaration doesn't name a type, return the inner declaration.
TemplateName getFriendTemplateName() const
static bool classofKind(Kind K)
FriendTemplateEntityKind getFriendKind() const
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
Definition Decl.h:2059
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2428
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition Decl.h:2496
bool isInstantiatedFromMemberTemplate() const
Definition Decl.h:2493
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
spec_iterator spec_end() const
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
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
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)
void addSpecialization(FunctionTemplateSpecializationInfo *Info, llvm::FoldingSetInsertToken InsertToken)
Add a specialization of this function template.
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:275
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:287
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:938
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, llvm::FoldingSetInsertToken InsertToken)
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
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
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
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)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void setMemberSpecialization()
Note that this member template is a specialization.
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:3857
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3948
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)
Represents a C++ template name within the type system.
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:3823
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:3649
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL=SourceLocation())
Definition Decl.h:3664
A container of type source information.
Definition TypeBase.h:8399
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2976
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9264
A set of unresolved declarations.
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T)
Definition Decl.h:719
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition Decl.cpp:2240
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:2749
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, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
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
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
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)
void AddSpecialization(VarTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
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.
Top level wrappers for InstallAPI frontend operations.
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:77
@ 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
const FunctionProtoType * T
@ 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:581
@ Concept
The name was classified as a concept name.
Definition Sema.h:585
@ VarTemplate
The name was classified as a variable template name.
Definition Sema.h:579
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:6014
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 ...