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 void *&InsertPos, ProfileArguments... ProfileArgs);
782
783 template <class EntryType, typename... ProfileArguments>
785 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
786 void *&InsertPos, ProfileArguments... ProfileArgs);
787
788 template <class Derived, class EntryType>
789 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
790 EntryType *Entry, void *InsertPos);
791
792 struct CommonBase {
794
795 /// The template from which this was most
796 /// directly instantiated (or null).
797 ///
798 /// The boolean value indicates whether this template
799 /// was explicitly specialized.
800 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
802 };
803
804 /// Pointer to the common data shared by all declarations of this
805 /// template.
806 mutable CommonBase *Common = nullptr;
807
808 /// Retrieves the "common" pointer shared by all (re-)declarations of
809 /// the same template. Calling this routine may implicitly allocate memory
810 /// for the common pointer.
811 CommonBase *getCommonPtr() const;
812
813 virtual CommonBase *newCommon(ASTContext &C) const = 0;
814
815 // Construct a template decl with name, parameters, and templated element.
819 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
820
821public:
822 friend class ASTDeclReader;
823 friend class ASTDeclWriter;
824 friend class ASTReader;
825 template <class decl_type> friend class RedeclarableTemplate;
826
827 /// Retrieves the canonical declaration of this template.
829 return getFirstDecl();
830 }
832 return getFirstDecl();
833 }
834
835 /// Determines whether this template was a specialization of a
836 /// member template.
837 ///
838 /// In the following example, the function template \c X<int>::f and the
839 /// member template \c X<int>::Inner are member specializations.
840 ///
841 /// \code
842 /// template<typename T>
843 /// struct X {
844 /// template<typename U> void f(T, U);
845 /// template<typename U> struct Inner;
846 /// };
847 ///
848 /// template<> template<typename T>
849 /// void X<int>::f(int, T);
850 /// template<> template<typename T>
851 /// struct X<int>::Inner { /* ... */ };
852 /// \endcode
854 return getCommonPtr()->InstantiatedFromMember.getInt();
855 }
856
857 /// Note that this member template is a specialization.
859 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
860 "Only member templates can be member template specializations");
861 getCommonPtr()->InstantiatedFromMember.setInt(true);
862 }
863
864 /// Retrieve the member template from which this template was
865 /// instantiated, or nullptr if this template was not instantiated from a
866 /// member template.
867 ///
868 /// A template is instantiated from a member template when the member
869 /// template itself is part of a class template (or member thereof). For
870 /// example, given
871 ///
872 /// \code
873 /// template<typename T>
874 /// struct X {
875 /// template<typename U> void f(T, U);
876 /// };
877 ///
878 /// void test(X<int> x) {
879 /// x.f(1, 'a');
880 /// };
881 /// \endcode
882 ///
883 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
884 /// template
885 ///
886 /// \code
887 /// template<typename U> void X<int>::f(int, U);
888 /// \endcode
889 ///
890 /// which was itself created during the instantiation of \c X<int>. Calling
891 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
892 /// retrieve the FunctionTemplateDecl for the original template \c f within
893 /// the class template \c X<T>, i.e.,
894 ///
895 /// \code
896 /// template<typename T>
897 /// template<typename U>
898 /// void X<T>::f(T, U);
899 /// \endcode
903
905 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
906 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
907 }
908
909 /// Retrieve the "injected" template arguments that correspond to the
910 /// template parameters of this template.
911 ///
912 /// Although the C++ standard has no notion of the "injected" template
913 /// arguments for a template, the notion is convenient when
914 /// we need to perform substitutions inside the definition of a template.
916 getInjectedTemplateArgs(const ASTContext &Context) const {
918 }
919
921 using redecl_iterator = redeclarable_base::redecl_iterator;
922
929
930 // Implement isa/cast/dyncast/etc.
931 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
932
933 static bool classofKind(Kind K) {
934 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
935 }
936};
937
938template <> struct RedeclarableTemplateDecl::
939SpecEntryTraits<FunctionTemplateSpecializationInfo> {
941
945
950};
951
952/// Declaration of a template function.
954protected:
955 friend class FunctionDecl;
956
957 /// Data that is common to all of the declarations of a given
958 /// function template.
960 /// The function template specializations for this function
961 /// template, including explicit specializations and instantiations.
962 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
963
964 Common() = default;
965 };
966
972
973 CommonBase *newCommon(ASTContext &C) const override;
974
976 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
977 }
978
979 /// Retrieve the set of function template specializations of this
980 /// function template.
981 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
982 getSpecializations() const;
983
984 /// Add a specialization of this function template.
985 ///
986 /// \param InsertPos Insert position in the FoldingSetVector, must have been
987 /// retrieved by an earlier call to findSpecialization().
989 void *InsertPos);
990
991public:
992 friend class ASTDeclReader;
993 friend class ASTDeclWriter;
994
995 /// Load any lazily-loaded specializations from the external source.
996 void LoadLazySpecializations() const;
997
998 /// Get the underlying function declaration of the template.
1000 return static_cast<FunctionDecl *>(TemplatedDecl);
1001 }
1002
1003 /// Returns whether this template declaration defines the primary
1004 /// pattern.
1008
1013
1014 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1015 // except this is per declaration, while the redeclarable field is
1016 // per chain. This indicates a template redeclaration which
1017 // is compatible with the definition, in the non-trivial case
1018 // where this is not already a definition.
1019 // This is only really needed for instantiating the definition of friend
1020 // function templates, which can have redeclarations in different template
1021 // contexts.
1022 // The bit is actually stored in the FunctionDecl for space efficiency
1023 // reasons.
1028
1029 /// Return the specialization with the provided arguments if it exists,
1030 /// otherwise return the insertion point.
1032 void *&InsertPos);
1033
1042
1043 /// Retrieve the previous declaration of this function template, or
1044 /// nullptr if no such declaration exists.
1046 return cast_or_null<FunctionTemplateDecl>(
1047 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1048 }
1050 return cast_or_null<FunctionTemplateDecl>(
1051 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1052 }
1053
1060 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1061 }
1062
1064 return cast_or_null<FunctionTemplateDecl>(
1066 }
1067
1069 using spec_range = llvm::iterator_range<spec_iterator>;
1070
1072 return spec_range(spec_begin(), spec_end());
1073 }
1074
1076 return makeSpecIterator(getSpecializations(), false);
1077 }
1078
1080 return makeSpecIterator(getSpecializations(), true);
1081 }
1082
1083 /// Return whether this function template is an abbreviated function template,
1084 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1085 bool isAbbreviated() const {
1086 // Since the invented template parameters generated from 'auto' parameters
1087 // are either appended to the end of the explicit template parameter list or
1088 // form a new template parameter list, we can simply observe the last
1089 // parameter to determine if such a thing happened.
1091 return TPL->getParam(TPL->size() - 1)->isImplicit();
1092 }
1093
1094 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1096
1097 /// Create a function template node.
1100 DeclarationName Name,
1101 TemplateParameterList *Params,
1102 NamedDecl *Decl);
1103
1104 /// Create an empty function template node.
1106 GlobalDeclID ID);
1107
1108 // Implement isa/cast/dyncast support
1109 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1110 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1111};
1112
1113//===----------------------------------------------------------------------===//
1114// Kinds of Template Parameters
1115//===----------------------------------------------------------------------===//
1116
1117/// Defines the position of a template parameter within a template
1118/// parameter list.
1119///
1120/// Because template parameter can be listed
1121/// sequentially for out-of-line template members, each template parameter is
1122/// given a Depth - the nesting of template parameter scopes - and a Position -
1123/// the occurrence within the parameter list.
1124/// This class is inheritedly privately by different kinds of template
1125/// parameters and is not part of the Decl hierarchy. Just a facility.
1127protected:
1128 enum { DepthWidth = 20, PositionWidth = 12 };
1129 unsigned Depth : DepthWidth;
1131
1132 TemplateParmPosition(int D, int P) {
1133 setDepth(D);
1134 setPosition(P);
1135 }
1136
1137public:
1139
1140 /// Get the nesting depth of the template parameter.
1141 unsigned getDepth() const { return Depth; }
1142 void setDepth(int D) {
1143 assert(D >= 0 && "The depth cannot be negative");
1144 assert(D < (1 << DepthWidth) && "The depth is too large");
1145 Depth = D;
1146 }
1147
1148 /// Get the position of the template parameter within its parameter list.
1149 unsigned getPosition() const { return Position; }
1150 void setPosition(int P) {
1151 assert(P >= 0 && "The position cannot be negative");
1152 assert(P < (1 << PositionWidth) && "The position is too large");
1153 Position = P;
1154 }
1155
1156 /// Get the index of the template parameter within its parameter list.
1157 unsigned getIndex() const { return Position; }
1158};
1159
1160/// Declaration of a template type parameter.
1161///
1162/// For example, "T" in
1163/// \code
1164/// template<typename T> class vector;
1165/// \endcode
1166class TemplateTypeParmDecl final : public TypeDecl,
1167 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1168 /// Sema creates these on the stack during auto type deduction.
1169 friend class Sema;
1170 friend TrailingObjects;
1171 friend class ASTDeclReader;
1172
1173 /// Whether this template type parameter was declaration with
1174 /// the 'typename' keyword.
1175 ///
1176 /// If false, it was declared with the 'class' keyword.
1177 bool Typename : 1;
1178
1179 /// Whether this template type parameter has a type-constraint construct.
1180 bool HasTypeConstraint : 1;
1181
1182 /// Whether the type constraint has been initialized. This can be false if the
1183 /// constraint was not initialized yet or if there was an error forming the
1184 /// type constraint.
1185 bool TypeConstraintInitialized : 1;
1186
1187 /// The number of type parameters in an expanded parameter pack, if any.
1188 UnsignedOrNone NumExpanded = std::nullopt;
1189
1190 /// The default template argument, if any.
1191 using DefArgStorage =
1193 DefArgStorage DefaultArgument;
1194
1195 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1196 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1197 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1198 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1199 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1200 NumExpanded(NumExpanded) {}
1201
1202public:
1203 static TemplateTypeParmDecl *
1204 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1205 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1206 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1207 UnsignedOrNone NumExpanded = std::nullopt);
1209 GlobalDeclID ID);
1211 GlobalDeclID ID,
1212 bool HasTypeConstraint);
1213
1214 /// Whether this template type parameter was declared with
1215 /// the 'typename' keyword.
1216 ///
1217 /// If not, it was either declared with the 'class' keyword or with a
1218 /// type-constraint (see hasTypeConstraint()).
1220 return Typename && !HasTypeConstraint;
1221 }
1222
1223 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1224
1225 /// Determine whether this template parameter has a default
1226 /// argument.
1227 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1228
1229 /// Retrieve the default argument, if any.
1231 static const TemplateArgumentLoc NoneLoc;
1232 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1233 }
1234
1235 /// Retrieves the location of the default argument declaration.
1237
1238 /// Determines whether the default argument was inherited
1239 /// from a previous declaration of this template.
1241 return DefaultArgument.isInherited();
1242 }
1243
1244 /// Set the default argument for this template parameter.
1245 void setDefaultArgument(const ASTContext &C,
1246 const TemplateArgumentLoc &DefArg);
1247
1248 /// Set that this default argument was inherited from another
1249 /// parameter.
1251 TemplateTypeParmDecl *Prev) {
1252 DefaultArgument.setInherited(C, Prev);
1253 }
1254
1255 /// Removes the default argument of this template parameter.
1257 DefaultArgument.clear();
1258 }
1259
1260 /// Set whether this template type parameter was declared with
1261 /// the 'typename' or 'class' keyword.
1262 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1263
1264 /// Retrieve the depth of the template parameter.
1265 unsigned getDepth() const;
1266
1267 /// Retrieve the index of the template parameter.
1268 unsigned getIndex() const;
1269
1270 /// Returns whether this is a parameter pack.
1271 bool isParameterPack() const;
1272
1273 /// Whether this parameter pack is a pack expansion.
1274 ///
1275 /// A template type template parameter pack can be a pack expansion if its
1276 /// type-constraint contains an unexpanded parameter pack.
1277 bool isPackExpansion() const {
1278 if (!isParameterPack())
1279 return false;
1280 if (const TypeConstraint *TC = getTypeConstraint())
1281 if (TC->hasExplicitTemplateArgs())
1282 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1283 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1284 return true;
1285 return false;
1286 }
1287
1288 /// Whether this parameter is a template type parameter pack that has a known
1289 /// list of different type-constraints at different positions.
1290 ///
1291 /// A parameter pack is an expanded parameter pack when the original
1292 /// parameter pack's type-constraint was itself a pack expansion, and that
1293 /// expansion has already been expanded. For example, given:
1294 ///
1295 /// \code
1296 /// template<typename ...Types>
1297 /// struct X {
1298 /// template<convertible_to<Types> ...Convertibles>
1299 /// struct Y { /* ... */ };
1300 /// };
1301 /// \endcode
1302 ///
1303 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1304 /// its type-constraint. When \c Types is supplied with template arguments by
1305 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1306 /// expanded parameter pack. For example, instantiating
1307 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1308 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1309 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1310 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1311
1312 /// Returns the type constraint associated with this template parameter (if
1313 /// any).
1315 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1316 }
1317
1319 Expr *ImmediatelyDeclaredConstraint,
1320 UnsignedOrNone ArgPackSubstIndex);
1321
1322 /// Determine whether this template parameter has a type-constraint.
1323 bool hasTypeConstraint() const {
1324 return HasTypeConstraint;
1325 }
1326
1327 /// \brief Get the associated-constraints of this template parameter.
1328 /// This will either be the immediately-introduced constraint or empty.
1329 ///
1330 /// Use this instead of getTypeConstraint for concepts APIs that
1331 /// accept an ArrayRef of constraint expressions.
1334 if (HasTypeConstraint)
1335 AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1336 getTypeConstraint()->getArgPackSubstIndex());
1337 }
1338
1339 SourceRange getSourceRange() const override LLVM_READONLY;
1340
1341 // Implement isa/cast/dyncast/etc.
1342 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1343 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1344};
1345
1346/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1347/// e.g., "Size" in
1348/// @code
1349/// template<int Size> class array { };
1350/// @endcode
1351class NonTypeTemplateParmDecl final
1352 : public DeclaratorDecl,
1353 protected TemplateParmPosition,
1354 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1355 std::pair<QualType, TypeSourceInfo *>,
1356 Expr *> {
1357 friend class ASTDeclReader;
1358 friend TrailingObjects;
1359
1360 /// The default template argument, if any, and whether or not
1361 /// it was inherited.
1362 using DefArgStorage =
1364 DefArgStorage DefaultArgument;
1365
1366 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1367 // down here to save memory.
1368
1369 /// Whether this non-type template parameter is a parameter pack.
1370 bool ParameterPack;
1371
1372 /// Whether this non-type template parameter is an "expanded"
1373 /// parameter pack, meaning that its type is a pack expansion and we
1374 /// already know the set of types that expansion expands to.
1375 bool ExpandedParameterPack = false;
1376
1377 /// The number of types in an expanded parameter pack.
1378 unsigned NumExpandedTypes = 0;
1379
1380 size_t numTrailingObjects(
1381 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1382 return NumExpandedTypes;
1383 }
1384
1386 SourceLocation IdLoc, int D, int P,
1387 const IdentifierInfo *Id, QualType T,
1388 bool ParameterPack, TypeSourceInfo *TInfo)
1389 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1390 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1391
1392 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1393 SourceLocation IdLoc, int D, int P,
1394 const IdentifierInfo *Id, QualType T,
1395 TypeSourceInfo *TInfo,
1396 ArrayRef<QualType> ExpandedTypes,
1397 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1398
1399public:
1400 static NonTypeTemplateParmDecl *
1401 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1402 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1403 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1404
1405 static NonTypeTemplateParmDecl *
1406 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1407 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1408 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1409 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1410
1411 static NonTypeTemplateParmDecl *
1412 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1413 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1414 GlobalDeclID ID,
1415 unsigned NumExpandedTypes,
1416 bool HasTypeConstraint);
1417
1423
1424 SourceRange getSourceRange() const override LLVM_READONLY;
1425
1426 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1427
1428 /// Determine whether this template parameter has a default
1429 /// argument.
1430 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1431
1432 /// Retrieve the default argument, if any.
1434 static const TemplateArgumentLoc NoneLoc;
1435 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1436 }
1437
1438 /// Retrieve the location of the default argument, if any.
1440
1441 /// Determines whether the default argument was inherited
1442 /// from a previous declaration of this template.
1444 return DefaultArgument.isInherited();
1445 }
1446
1447 /// Set the default argument for this template parameter, and
1448 /// whether that default argument was inherited from another
1449 /// declaration.
1450 void setDefaultArgument(const ASTContext &C,
1451 const TemplateArgumentLoc &DefArg);
1453 NonTypeTemplateParmDecl *Parm) {
1454 DefaultArgument.setInherited(C, Parm);
1455 }
1456
1457 /// Removes the default argument of this template parameter.
1458 void removeDefaultArgument() { DefaultArgument.clear(); }
1459
1460 /// Whether this parameter is a non-type template parameter pack.
1461 ///
1462 /// If the parameter is a parameter pack, the type may be a
1463 /// \c PackExpansionType. In the following example, the \c Dims parameter
1464 /// is a parameter pack (whose type is 'unsigned').
1465 ///
1466 /// \code
1467 /// template<typename T, unsigned ...Dims> struct multi_array;
1468 /// \endcode
1469 bool isParameterPack() const { return ParameterPack; }
1470
1471 /// Whether this parameter pack is a pack expansion.
1472 ///
1473 /// A non-type template parameter pack is a pack expansion if its type
1474 /// contains an unexpanded parameter pack. In this case, we will have
1475 /// built a PackExpansionType wrapping the type.
1476 bool isPackExpansion() const {
1477 return ParameterPack && getType()->getAs<PackExpansionType>();
1478 }
1479
1480 /// Whether this parameter is a non-type template parameter pack
1481 /// that has a known list of different types at different positions.
1482 ///
1483 /// A parameter pack is an expanded parameter pack when the original
1484 /// parameter pack's type was itself a pack expansion, and that expansion
1485 /// has already been expanded. For example, given:
1486 ///
1487 /// \code
1488 /// template<typename ...Types>
1489 /// struct X {
1490 /// template<Types ...Values>
1491 /// struct Y { /* ... */ };
1492 /// };
1493 /// \endcode
1494 ///
1495 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1496 /// which expands \c Types. When \c Types is supplied with template arguments
1497 /// by instantiating \c X, the instantiation of \c Values becomes an
1498 /// expanded parameter pack. For example, instantiating
1499 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1500 /// pack with expansion types \c int and \c unsigned int.
1501 ///
1502 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1503 /// return the expansion types.
1504 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1505
1506 /// Retrieves the number of expansion types in an expanded parameter
1507 /// pack.
1508 unsigned getNumExpansionTypes() const {
1509 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1510 return NumExpandedTypes;
1511 }
1512
1513 /// Retrieve a particular expansion type within an expanded parameter
1514 /// pack.
1515 QualType getExpansionType(unsigned I) const {
1516 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1517 auto TypesAndInfos =
1518 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1519 return TypesAndInfos[I].first;
1520 }
1521
1522 /// Retrieve a particular expansion type source info within an
1523 /// expanded parameter pack.
1525 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1526 auto TypesAndInfos =
1527 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1528 return TypesAndInfos[I].second;
1529 }
1530
1531 /// Return the constraint introduced by the placeholder type of this non-type
1532 /// template parameter (if any).
1534 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1535 nullptr;
1536 }
1537
1539 *getTrailingObjects<Expr *>() = E;
1540 }
1541
1542 /// Determine whether this non-type template parameter's type has a
1543 /// placeholder with a type-constraint.
1545 auto *AT = getType()->getContainedAutoType();
1546 return AT && AT->isConstrained();
1547 }
1548
1549 /// \brief Get the associated-constraints of this template parameter.
1550 /// This will either be a vector of size 1 containing the immediately-declared
1551 /// constraint introduced by the placeholder type, or an empty vector.
1552 ///
1553 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1554 /// concepts APIs that accept an ArrayRef of constraint expressions.
1558 AC.emplace_back(E);
1559 }
1560
1561 // Implement isa/cast/dyncast/etc.
1562 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1563 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1564};
1565
1566/// TemplateTemplateParmDecl - Declares a template template parameter,
1567/// e.g., "T" in
1568/// @code
1569/// template <template <typename> class T> class container { };
1570/// @endcode
1571/// A template template parameter is a TemplateDecl because it defines the
1572/// name of a template and the template parameters allowable for substitution.
1573class TemplateTemplateParmDecl final
1574 : public TemplateDecl,
1575 protected TemplateParmPosition,
1576 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1577 TemplateParameterList *> {
1578 /// The default template argument, if any.
1579 using DefArgStorage =
1581 DefArgStorage DefaultArgument;
1582
1583 LLVM_PREFERRED_TYPE(TemplateNameKind)
1584 unsigned ParameterKind : 3;
1585
1586 /// Whether this template template parameter was declaration with
1587 /// the 'typename' keyword.
1588 ///
1589 /// If false, it was declared with the 'class' keyword.
1590 LLVM_PREFERRED_TYPE(bool)
1591 unsigned Typename : 1;
1592
1593 /// Whether this parameter is a parameter pack.
1594 LLVM_PREFERRED_TYPE(bool)
1595 unsigned ParameterPack : 1;
1596
1597 /// Whether this template template parameter is an "expanded"
1598 /// parameter pack, meaning that it is a pack expansion and we
1599 /// already know the set of template parameters that expansion expands to.
1600 LLVM_PREFERRED_TYPE(bool)
1601 unsigned ExpandedParameterPack : 1;
1602
1603 /// The number of parameters in an expanded parameter pack.
1604 unsigned NumExpandedParams = 0;
1605
1606 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1607 bool ParameterPack, IdentifierInfo *Id,
1608 TemplateNameKind ParameterKind, bool Typename,
1609 TemplateParameterList *Params)
1610 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1611 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1612 Typename(Typename), ParameterPack(ParameterPack),
1613 ExpandedParameterPack(false) {}
1614
1615 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1616 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1617 bool Typename, TemplateParameterList *Params,
1619
1620 void anchor() override;
1621
1622public:
1623 friend class ASTDeclReader;
1624 friend class ASTDeclWriter;
1626
1627 static TemplateTemplateParmDecl *
1628 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1629 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1630 bool Typename, TemplateParameterList *Params);
1631
1632 static TemplateTemplateParmDecl *
1633 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1634 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1635 TemplateParameterList *Params,
1637
1638 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1639 GlobalDeclID ID);
1640 static TemplateTemplateParmDecl *
1641 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1642
1648
1649 /// Whether this template template parameter was declared with
1650 /// the 'typename' keyword.
1651 bool wasDeclaredWithTypename() const { return Typename; }
1652
1653 /// Set whether this template template parameter was declared with
1654 /// the 'typename' or 'class' keyword.
1655 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1656
1657 /// Whether this template template parameter is a template
1658 /// parameter pack.
1659 ///
1660 /// \code
1661 /// template<template <class T> ...MetaFunctions> struct Apply;
1662 /// \endcode
1663 bool isParameterPack() const { return ParameterPack; }
1664
1665 /// Whether this parameter pack is a pack expansion.
1666 ///
1667 /// A template template parameter pack is a pack expansion if its template
1668 /// parameter list contains an unexpanded parameter pack.
1669 bool isPackExpansion() const {
1670 return ParameterPack &&
1672 }
1673
1674 /// Whether this parameter is a template template parameter pack that
1675 /// has a known list of different template parameter lists at different
1676 /// positions.
1677 ///
1678 /// A parameter pack is an expanded parameter pack when the original parameter
1679 /// pack's template parameter list was itself a pack expansion, and that
1680 /// expansion has already been expanded. For exampe, given:
1681 ///
1682 /// \code
1683 /// template<typename...Types> struct Outer {
1684 /// template<template<Types> class...Templates> struct Inner;
1685 /// };
1686 /// \endcode
1687 ///
1688 /// The parameter pack \c Templates is a pack expansion, which expands the
1689 /// pack \c Types. When \c Types is supplied with template arguments by
1690 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1691 /// parameter pack.
1692 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1693
1694 /// Retrieves the number of expansion template parameters in
1695 /// an expanded parameter pack.
1697 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1698 return NumExpandedParams;
1699 }
1700
1701 /// Retrieve a particular expansion type within an expanded parameter
1702 /// pack.
1704 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1705 return getTrailingObjects()[I];
1706 }
1707
1708 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1709
1710 /// Determine whether this template parameter has a default
1711 /// argument.
1712 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1713
1714 /// Retrieve the default argument, if any.
1716 static const TemplateArgumentLoc NoneLoc;
1717 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1718 }
1719
1720 /// Retrieve the location of the default argument, if any.
1722
1723 /// Determines whether the default argument was inherited
1724 /// from a previous declaration of this template.
1726 return DefaultArgument.isInherited();
1727 }
1728
1729 /// Set the default argument for this template parameter, and
1730 /// whether that default argument was inherited from another
1731 /// declaration.
1732 void setDefaultArgument(const ASTContext &C,
1733 const TemplateArgumentLoc &DefArg);
1735 TemplateTemplateParmDecl *Prev) {
1736 DefaultArgument.setInherited(C, Prev);
1737 }
1738
1739 /// Removes the default argument of this template parameter.
1740 void removeDefaultArgument() { DefaultArgument.clear(); }
1741
1742 SourceRange getSourceRange() const override LLVM_READONLY {
1746 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1747 }
1748
1750 return static_cast<TemplateNameKind>(ParameterKind);
1751 }
1752
1758
1759 // Implement isa/cast/dyncast/etc.
1760 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1761 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1762};
1763
1764/// Represents the builtin template declaration which is used to
1765/// implement __make_integer_seq and other builtin templates. It serves
1766/// no real purpose beyond existing as a place to hold template parameters.
1767class BuiltinTemplateDecl : public TemplateDecl {
1769
1770 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1772
1773 void anchor() override;
1774
1775public:
1776 // Implement isa/cast/dyncast support
1777 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1778 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1779
1780 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1781 DeclarationName Name,
1782 BuiltinTemplateKind BTK) {
1783 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1784 }
1785
1786 SourceRange getSourceRange() const override LLVM_READONLY {
1787 return {};
1788 }
1789
1791
1792 bool isPackProducingBuiltinTemplate() const;
1793};
1795
1796/// Provides information about an explicit instantiation of a variable or class
1797/// template.
1799 /// The template arguments as written..
1801
1802 /// The location of the extern keyword.
1804
1805 /// The location of the template keyword.
1807
1809};
1810
1812 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1814
1815/// Represents a class template specialization, which refers to
1816/// a class template with a given set of template arguments.
1817///
1818/// Class template specializations represent both explicit
1819/// specialization of class templates, as in the example below, and
1820/// implicit instantiations of class templates.
1821///
1822/// \code
1823/// template<typename T> class array;
1824///
1825/// template<>
1826/// class array<bool> { }; // class template specialization array<bool>
1827/// \endcode
1829 public llvm::FoldingSetNode {
1830 /// Structure that stores information about a class template
1831 /// specialization that was instantiated from a class template partial
1832 /// specialization.
1833 struct SpecializedPartialSpecialization {
1834 /// The class template partial specialization from which this
1835 /// class template specialization was instantiated.
1836 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1837
1838 /// The template argument list deduced for the class template
1839 /// partial specialization itself.
1840 const TemplateArgumentList *TemplateArgs;
1841 };
1842
1843 /// The template that this specialization specializes
1844 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1845 SpecializedTemplate;
1846
1847 /// Further info for explicit template specialization/instantiation.
1848 /// Does not apply to implicit specializations.
1849 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1850
1851 /// The template arguments used to describe this specialization.
1852 const TemplateArgumentList *TemplateArgs;
1853
1854 /// The point where this template was instantiated (if any)
1855 SourceLocation PointOfInstantiation;
1856
1857 /// The kind of specialization this declaration refers to.
1858 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1859 unsigned SpecializationKind : 3;
1860
1861 /// Indicate that we have matched a parameter pack with a non pack
1862 /// argument, when the opposite match is also allowed.
1863 /// This needs to be cached as deduction is performed during declaration,
1864 /// and we need the information to be preserved so that it is consistent
1865 /// during instantiation.
1866 LLVM_PREFERRED_TYPE(bool)
1867 unsigned StrictPackMatch : 1;
1868
1869protected:
1871 DeclContext *DC, SourceLocation StartLoc,
1872 SourceLocation IdLoc,
1873 ClassTemplateDecl *SpecializedTemplate,
1875 bool StrictPackMatch,
1877
1879
1880public:
1881 friend class ASTDeclReader;
1882 friend class ASTDeclWriter;
1883
1885 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1886 SourceLocation StartLoc, SourceLocation IdLoc,
1887 ClassTemplateDecl *SpecializedTemplate,
1888 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1891 GlobalDeclID ID);
1892
1893 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1894 bool Qualified) const override;
1895
1900
1905
1906 /// Retrieve the template that this specialization specializes.
1908
1909 /// Retrieve the template arguments of the class template
1910 /// specialization.
1912 return *TemplateArgs;
1913 }
1914
1916 TemplateArgs = Args;
1917 }
1918
1919 /// Determine the kind of specialization that this
1920 /// declaration represents.
1922 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1923 }
1924
1928
1929 /// Is this an explicit specialization at class scope (within the class that
1930 /// owns the primary template)? For example:
1931 ///
1932 /// \code
1933 /// template<typename T> struct Outer {
1934 /// template<typename U> struct Inner;
1935 /// template<> struct Inner; // class-scope explicit specialization
1936 /// };
1937 /// \endcode
1942
1943 /// True if this declaration is an explicit specialization,
1944 /// explicit instantiation declaration, or explicit instantiation
1945 /// definition.
1950
1952 SpecializedTemplate = Specialized;
1953 }
1954
1956 SpecializationKind = TSK;
1957 }
1958
1959 bool hasStrictPackMatch() const { return StrictPackMatch; }
1960
1961 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1962
1963 /// Get the point of instantiation (if any), or null if none.
1965 return PointOfInstantiation;
1966 }
1967
1969 assert(Loc.isValid() && "point of instantiation must be valid!");
1970 PointOfInstantiation = Loc;
1971 }
1972
1973 /// If this class template specialization is an instantiation of
1974 /// a template (rather than an explicit specialization), return the
1975 /// class template or class template partial specialization from which it
1976 /// was instantiated.
1977 llvm::PointerUnion<ClassTemplateDecl *,
1981 return llvm::PointerUnion<ClassTemplateDecl *,
1983
1985 }
1986
1987 /// Retrieve the class template or class template partial
1988 /// specialization which was specialized by this.
1989 llvm::PointerUnion<ClassTemplateDecl *,
1992 if (const auto *PartialSpec =
1993 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1994 return PartialSpec->PartialSpecialization;
1995
1996 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1997 }
1998
1999 /// Retrieve the set of template arguments that should be used
2000 /// to instantiate members of the class template or class template partial
2001 /// specialization from which this class template specialization was
2002 /// instantiated.
2003 ///
2004 /// \returns For a class template specialization instantiated from the primary
2005 /// template, this function will return the same template arguments as
2006 /// getTemplateArgs(). For a class template specialization instantiated from
2007 /// a class template partial specialization, this function will return the
2008 /// deduced template arguments for the class template partial specialization
2009 /// itself.
2011 if (const auto *PartialSpec =
2012 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2013 return *PartialSpec->TemplateArgs;
2014
2015 return getTemplateArgs();
2016 }
2017
2018 /// Note that this class template specialization is actually an
2019 /// instantiation of the given class template partial specialization whose
2020 /// template arguments have been deduced.
2022 const TemplateArgumentList *TemplateArgs) {
2023 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2024 "Already set to a class template partial specialization!");
2025 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2026 PS->PartialSpecialization = PartialSpec;
2027 PS->TemplateArgs = TemplateArgs;
2028 SpecializedTemplate = PS;
2029 }
2030
2031 /// Note that this class template specialization is an instantiation
2032 /// of the given class template.
2034 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2035 "Previously set to a class template partial specialization!");
2036 SpecializedTemplate = TemplDecl;
2037 }
2038
2039 /// Retrieve the template argument list as written in the sources,
2040 /// if any.
2042 if (auto *Info =
2043 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2044 return Info->TemplateArgsAsWritten;
2045 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2046 }
2047
2048 /// Set the template argument list as written in the sources.
2049 void
2051 if (auto *Info =
2052 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2053 Info->TemplateArgsAsWritten = ArgsWritten;
2054 else
2055 ExplicitInfo = ArgsWritten;
2056 }
2057
2058 /// Set the template argument list as written in the sources.
2063
2064 /// Gets the location of the extern keyword, if present.
2066 if (auto *Info =
2067 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2068 return Info->ExternKeywordLoc;
2069 return SourceLocation();
2070 }
2071
2072 /// Sets the location of the extern keyword.
2074
2075 /// Gets the location of the template keyword, if present.
2077 if (auto *Info =
2078 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2079 return Info->TemplateKeywordLoc;
2080 return SourceLocation();
2081 }
2082
2083 /// Sets the location of the template keyword.
2085
2086 SourceRange getSourceRange() const override LLVM_READONLY;
2087
2088 void Profile(llvm::FoldingSetNodeID &ID) const {
2089 Profile(ID, TemplateArgs->asArray(), getASTContext());
2090 }
2091
2092 static void
2093 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2094 const ASTContext &Context) {
2095 ID.AddInteger(TemplateArgs.size());
2096 for (const TemplateArgument &TemplateArg : TemplateArgs)
2097 TemplateArg.Profile(ID, Context);
2098 }
2099
2100 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2101
2102 static bool classofKind(Kind K) {
2103 return K >= firstClassTemplateSpecialization &&
2104 K <= lastClassTemplateSpecialization;
2105 }
2106};
2107
2108class ClassTemplatePartialSpecializationDecl
2110 /// The list of template parameters
2111 TemplateParameterList *TemplateParams = nullptr;
2112
2113 /// The class template partial specialization from which this
2114 /// class template partial specialization was instantiated.
2115 ///
2116 /// The boolean value will be true to indicate that this class template
2117 /// partial specialization was specialized at this level.
2118 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2119 InstantiatedFromMember;
2120
2121 mutable CanQualType CanonInjectedTST;
2122
2123 ClassTemplatePartialSpecializationDecl(
2124 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2126 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2127 CanQualType CanonInjectedTST,
2128 ClassTemplatePartialSpecializationDecl *PrevDecl);
2129
2130 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2131 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2132 InstantiatedFromMember(nullptr, false) {}
2133
2134 void anchor() override;
2135
2136public:
2137 friend class ASTDeclReader;
2138 friend class ASTDeclWriter;
2139
2140 static ClassTemplatePartialSpecializationDecl *
2141 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2142 SourceLocation StartLoc, SourceLocation IdLoc,
2143 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2144 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2145 ClassTemplatePartialSpecializationDecl *PrevDecl);
2146
2147 static ClassTemplatePartialSpecializationDecl *
2149
2150 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2152 static_cast<ClassTemplateSpecializationDecl *>(
2153 this)->getMostRecentDecl());
2154 }
2155
2156 /// Get the list of template parameters
2158 return TemplateParams;
2159 }
2160
2161 /// \brief All associated constraints of this partial specialization,
2162 /// including the requires clause and any constraints derived from
2163 /// constrained-parameters.
2164 ///
2165 /// The constraints in the resulting list are to be treated as if in a
2166 /// conjunction ("and").
2169 TemplateParams->getAssociatedConstraints(AC);
2170 }
2171
2173 return TemplateParams->hasAssociatedConstraints();
2174 }
2175
2176 /// Retrieve the member class template partial specialization from
2177 /// which this particular class template partial specialization was
2178 /// instantiated.
2179 ///
2180 /// \code
2181 /// template<typename T>
2182 /// struct Outer {
2183 /// template<typename U> struct Inner;
2184 /// template<typename U> struct Inner<U*> { }; // #1
2185 /// };
2186 ///
2187 /// Outer<float>::Inner<int*> ii;
2188 /// \endcode
2189 ///
2190 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2191 /// end up instantiating the partial specialization
2192 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2193 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2194 /// \c Outer<float>::Inner<U*>, this function would return
2195 /// \c Outer<T>::Inner<U*>.
2196 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2197 const auto *First =
2199 return First->InstantiatedFromMember.getPointer();
2200 }
2205
2207 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2209 First->InstantiatedFromMember.setPointer(PartialSpec);
2210 }
2211
2212 /// Determines whether this class template partial specialization
2213 /// template was a specialization of a member partial specialization.
2214 ///
2215 /// In the following example, the member template partial specialization
2216 /// \c X<int>::Inner<T*> is a member specialization.
2217 ///
2218 /// \code
2219 /// template<typename T>
2220 /// struct X {
2221 /// template<typename U> struct Inner;
2222 /// template<typename U> struct Inner<U*>;
2223 /// };
2224 ///
2225 /// template<> template<typename T>
2226 /// struct X<int>::Inner<T*> { /* ... */ };
2227 /// \endcode
2229 const auto *First =
2231 return First->InstantiatedFromMember.getInt();
2232 }
2233
2234 /// Note that this member template is a specialization.
2235 /// A partial specialization may be a member specialization even if it is not
2236 /// an instantiation of a member partial specialization.
2239 return First->InstantiatedFromMember.setInt(true);
2240 }
2241
2242 /// Retrieves the canonical injected specialization type for this partial
2243 /// specialization.
2246
2247 SourceRange getSourceRange() const override LLVM_READONLY;
2248
2249 void Profile(llvm::FoldingSetNodeID &ID) const {
2251 getASTContext());
2252 }
2253
2254 static void
2255 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2256 TemplateParameterList *TPL, const ASTContext &Context);
2257
2258 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2259
2260 static bool classofKind(Kind K) {
2261 return K == ClassTemplatePartialSpecialization;
2262 }
2263};
2264
2265/// Declaration of a class template.
2267protected:
2268 /// Data that is common to all of the declarations of a given
2269 /// class template.
2271 /// The class template specializations for this class
2272 /// template, including explicit specializations and instantiations.
2273 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2274
2275 /// The class template partial specializations for this class
2276 /// template.
2277 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2279
2280 /// The Injected Template Specialization Type for this declaration.
2282
2283 Common() = default;
2284 };
2285
2286 /// Retrieve the set of specializations of this class template.
2287 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2288 getSpecializations() const;
2289
2290 /// Retrieve the set of partial specializations of this class
2291 /// template.
2292 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2294
2297 NamedDecl *Decl)
2298 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2299
2300 CommonBase *newCommon(ASTContext &C) const override;
2301
2303 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2304 }
2305
2307
2308public:
2309
2310 friend class ASTDeclReader;
2311 friend class ASTDeclWriter;
2313
2314 /// Load any lazily-loaded specializations from the external source.
2315 void LoadLazySpecializations(bool OnlyPartial = false) const;
2316
2317 /// Get the underlying class declarations of the template.
2319 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2320 }
2321
2322 /// Returns whether this template declaration defines the primary
2323 /// class pattern.
2327
2328 /// \brief Create a class template node.
2331 DeclarationName Name,
2332 TemplateParameterList *Params,
2333 NamedDecl *Decl);
2334
2335 /// Create an empty class template node.
2337
2338 /// Return the specialization with the provided arguments if it exists,
2339 /// otherwise return the insertion point.
2341 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2342
2343 /// Insert the specified specialization knowing that it is not already
2344 /// in. InsertPos must be obtained from findSpecialization.
2345 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2346
2355
2356 /// Retrieve the previous declaration of this class template, or
2357 /// nullptr if no such declaration exists.
2359 return cast_or_null<ClassTemplateDecl>(
2360 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2361 }
2363 return cast_or_null<ClassTemplateDecl>(
2364 static_cast<const RedeclarableTemplateDecl *>(
2365 this)->getPreviousDecl());
2366 }
2367
2373 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2374 }
2375
2377 return cast_or_null<ClassTemplateDecl>(
2379 }
2380
2381 /// Return the partial specialization with the provided arguments if it
2382 /// exists, otherwise return the insertion point.
2385 TemplateParameterList *TPL, void *&InsertPos);
2386
2387 /// Insert the specified partial specialization knowing that it is not
2388 /// already in. InsertPos must be obtained from findPartialSpecialization.
2390 void *InsertPos);
2391
2392 /// Retrieve the partial specializations as an ordered list.
2395
2396 /// Find a class template partial specialization with the given
2397 /// type T.
2398 ///
2399 /// \param T a dependent type that names a specialization of this class
2400 /// template.
2401 ///
2402 /// \returns the class template partial specialization that exactly matches
2403 /// the type \p T, or nullptr if no such partial specialization exists.
2405
2406 /// Find a class template partial specialization which was instantiated
2407 /// from the given member partial specialization.
2408 ///
2409 /// \param D a member class template partial specialization.
2410 ///
2411 /// \returns the class template partial specialization which was instantiated
2412 /// from the given member partial specialization, or nullptr if no such
2413 /// partial specialization exists.
2417
2418 /// Retrieve the canonical template specialization type of the
2419 /// injected-class-name for this class template.
2420 ///
2421 /// The injected-class-name for a class template \c X is \c
2422 /// X<template-args>, where \c template-args is formed from the
2423 /// template arguments that correspond to the template parameters of
2424 /// \c X. For example:
2425 ///
2426 /// \code
2427 /// template<typename T, int N>
2428 /// struct array {
2429 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2430 /// };
2431 /// \endcode
2434
2436 using spec_range = llvm::iterator_range<spec_iterator>;
2437
2439 return spec_range(spec_begin(), spec_end());
2440 }
2441
2443 return makeSpecIterator(getSpecializations(), false);
2444 }
2445
2447 return makeSpecIterator(getSpecializations(), true);
2448 }
2449
2450 // Implement isa/cast/dyncast support
2451 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2452 static bool classofKind(Kind K) { return K == ClassTemplate; }
2453};
2454
2455/// Declaration of a friend template.
2456///
2457/// For example:
2458/// \code
2459/// template <typename T> class A {
2460/// friend class MyVector<T>; // not a friend template
2461/// template <typename U> friend class B; // friend class template
2462/// template <typename U> friend class Foo<T>::Nested; // friend template
2463/// };
2464/// \endcode
2465class FriendTemplateDecl final
2466 : public FriendDecl,
2467 private llvm::TrailingObjects<FriendTemplateDecl,
2468 TemplateParameterList *> {
2469 void anchor() override;
2470
2471private:
2472 unsigned NumTPLists = 0;
2473 TemplateName Template;
2474
2475 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, FriendUnion Friend,
2476 SourceLocation FriendLoc, SourceLocation EllipsisLoc,
2478 TemplateName Template = {})
2479 : FriendDecl(Decl::FriendTemplate, DC, Loc, Friend, FriendLoc,
2480 EllipsisLoc),
2481 NumTPLists(FriendTPLists.size()), Template(Template) {
2482 assert(!FriendTPLists.empty());
2483 llvm::copy(FriendTPLists, getTrailingObjects());
2484 }
2485
2486 FriendTemplateDecl(EmptyShell Empty, unsigned NumFriendTPLists)
2487 : FriendDecl(Decl::FriendTemplate, Empty), NumTPLists(NumFriendTPLists) {
2488 assert(NumFriendTPLists != 0);
2489 }
2490
2491public:
2492 friend class ASTDeclReader;
2493 friend class ASTDeclWriter;
2495
2496 enum class FriendTemplateEntityKind { Type, Template, Decl };
2497
2498 static FriendTemplateDecl *
2499 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2502 SourceLocation EllipsisLoc = {}, TemplateName Template = {});
2503
2504 static FriendTemplateDecl *
2505 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2506 TemplateName Template, SourceLocation FriendLoc,
2507 ArrayRef<TemplateParameterList *> FriendTPLists,
2508 SourceLocation EllipsisLoc = {});
2509
2510 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
2511 unsigned NumFriendTPLists);
2512
2513 SourceRange getSourceRange() const override LLVM_READONLY;
2514
2515 TemplateName getFriendTemplateName() const { return Template; }
2516
2518 if (getFriendType())
2520 if (Template.isNull())
2523 }
2524
2525 NamedDecl *getFriendDecl() const override {
2526 if (NamedDecl *ND = Friend.dyn_cast<NamedDecl *>())
2527 return ND;
2528 return Template.getAsTemplateDecl();
2529 }
2530
2532 return ArrayRef(getTrailingObjects(), NumTPLists);
2533 }
2534
2535 // Implement isa/cast/dyncast/etc.
2536 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2537 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2538};
2539
2540/// Declaration of an alias template.
2541///
2542/// For example:
2543/// \code
2544/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2545/// \endcode
2547protected:
2549
2555
2556 CommonBase *newCommon(ASTContext &C) const override;
2557
2559 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2560 }
2561
2562public:
2563 friend class ASTDeclReader;
2564 friend class ASTDeclWriter;
2565
2566 /// Get the underlying function declaration of the template.
2568 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2569 }
2570
2571
2580
2581 /// Retrieve the previous declaration of this function template, or
2582 /// nullptr if no such declaration exists.
2584 return cast_or_null<TypeAliasTemplateDecl>(
2585 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2586 }
2588 return cast_or_null<TypeAliasTemplateDecl>(
2589 static_cast<const RedeclarableTemplateDecl *>(
2590 this)->getPreviousDecl());
2591 }
2592
2594 return cast_or_null<TypeAliasTemplateDecl>(
2596 }
2597
2598 /// Create a function template node.
2601 DeclarationName Name,
2602 TemplateParameterList *Params,
2603 NamedDecl *Decl);
2604
2605 /// Create an empty alias template node.
2607 GlobalDeclID ID);
2608
2609 // Implement isa/cast/dyncast support
2610 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2611 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2612};
2613
2614/// Represents a variable template specialization, which refers to
2615/// a variable template with a given set of template arguments.
2616///
2617/// Variable template specializations represent both explicit
2618/// specializations of variable templates, as in the example below, and
2619/// implicit instantiations of variable templates.
2620///
2621/// \code
2622/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2623///
2624/// template<>
2625/// constexpr float pi<float>; // variable template specialization pi<float>
2626/// \endcode
2628 public llvm::FoldingSetNode {
2629
2630 /// Structure that stores information about a variable template
2631 /// specialization that was instantiated from a variable template partial
2632 /// specialization.
2633 struct SpecializedPartialSpecialization {
2634 /// The variable template partial specialization from which this
2635 /// variable template specialization was instantiated.
2636 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2637
2638 /// The template argument list deduced for the variable template
2639 /// partial specialization itself.
2640 const TemplateArgumentList *TemplateArgs;
2641 };
2642
2643 /// The template that this specialization specializes.
2644 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2645 SpecializedTemplate;
2646
2647 /// Further info for explicit template specialization/instantiation.
2648 /// Does not apply to implicit specializations.
2649 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2650
2651 /// The template arguments used to describe this specialization.
2652 const TemplateArgumentList *TemplateArgs;
2653
2654 /// The point where this template was instantiated (if any).
2655 SourceLocation PointOfInstantiation;
2656
2657 /// The kind of specialization this declaration refers to.
2658 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2659 unsigned SpecializationKind : 3;
2660
2661 /// Whether this declaration is a complete definition of the
2662 /// variable template specialization. We can't otherwise tell apart
2663 /// an instantiated declaration from an instantiated definition with
2664 /// no initializer.
2665 LLVM_PREFERRED_TYPE(bool)
2666 unsigned IsCompleteDefinition : 1;
2667
2668protected:
2670 SourceLocation StartLoc, SourceLocation IdLoc,
2671 VarTemplateDecl *SpecializedTemplate,
2672 QualType T, TypeSourceInfo *TInfo,
2673 StorageClass S,
2675
2676 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2677
2678public:
2679 friend class ASTDeclReader;
2680 friend class ASTDeclWriter;
2681 friend class VarDecl;
2682
2684 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2685 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2686 TypeSourceInfo *TInfo, StorageClass S,
2689 GlobalDeclID ID);
2690
2691 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2692 bool Qualified) const override;
2693
2695 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2697 }
2698
2699 /// Retrieve the template that this specialization specializes.
2701
2702 /// Retrieve the template arguments of the variable template
2703 /// specialization.
2704 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2705
2706 /// Determine the kind of specialization that this
2707 /// declaration represents.
2709 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2710 }
2711
2715
2720
2721 /// True if this declaration is an explicit specialization,
2722 /// explicit instantiation declaration, or explicit instantiation
2723 /// definition.
2728
2730 SpecializationKind = TSK;
2731 }
2732
2733 /// Get the point of instantiation (if any), or null if none.
2735 return PointOfInstantiation;
2736 }
2737
2739 assert(Loc.isValid() && "point of instantiation must be valid!");
2740 PointOfInstantiation = Loc;
2741 }
2742
2743 void setCompleteDefinition() { IsCompleteDefinition = true; }
2744
2745 /// If this variable template specialization is an instantiation of
2746 /// a template (rather than an explicit specialization), return the
2747 /// variable template or variable template partial specialization from which
2748 /// it was instantiated.
2749 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2752 return llvm::PointerUnion<VarTemplateDecl *,
2754
2756 }
2757
2758 /// Retrieve the variable template or variable template partial
2759 /// specialization which was specialized by this.
2760 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2762 if (const auto *PartialSpec =
2763 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2764 return PartialSpec->PartialSpecialization;
2765
2766 return cast<VarTemplateDecl *>(SpecializedTemplate);
2767 }
2768
2769 /// Retrieve the set of template arguments that should be used
2770 /// to instantiate the initializer of the variable template or variable
2771 /// template partial specialization from which this variable template
2772 /// specialization was instantiated.
2773 ///
2774 /// \returns For a variable template specialization instantiated from the
2775 /// primary template, this function will return the same template arguments
2776 /// as getTemplateArgs(). For a variable template specialization instantiated
2777 /// from a variable template partial specialization, this function will the
2778 /// return deduced template arguments for the variable template partial
2779 /// specialization itself.
2781 if (const auto *PartialSpec =
2782 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2783 return *PartialSpec->TemplateArgs;
2784
2785 return getTemplateArgs();
2786 }
2787
2788 /// Note that this variable template specialization is actually an
2789 /// instantiation of the given variable template partial specialization whose
2790 /// template arguments have been deduced.
2792 const TemplateArgumentList *TemplateArgs) {
2793 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2794 "Already set to a variable template partial specialization!");
2795 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2796 PS->PartialSpecialization = PartialSpec;
2797 PS->TemplateArgs = TemplateArgs;
2798 SpecializedTemplate = PS;
2799 }
2800
2801 /// Note that this variable template specialization is an instantiation
2802 /// of the given variable template.
2804 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2805 "Previously set to a variable template partial specialization!");
2806 SpecializedTemplate = TemplDecl;
2807 }
2808
2809 /// Retrieve the template argument list as written in the sources,
2810 /// if any.
2812 if (auto *Info =
2813 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2814 return Info->TemplateArgsAsWritten;
2815 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2816 }
2817
2818 /// Set the template argument list as written in the sources.
2819 void
2821 if (auto *Info =
2822 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2823 Info->TemplateArgsAsWritten = ArgsWritten;
2824 else
2825 ExplicitInfo = ArgsWritten;
2826 }
2827
2828 /// Set the template argument list as written in the sources.
2833
2834 /// Gets the location of the extern keyword, if present.
2836 if (auto *Info =
2837 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2838 return Info->ExternKeywordLoc;
2839 return SourceLocation();
2840 }
2841
2842 /// Sets the location of the extern keyword.
2844
2845 /// Gets the location of the template keyword, if present.
2847 if (auto *Info =
2848 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2849 return Info->TemplateKeywordLoc;
2850 return SourceLocation();
2851 }
2852
2853 /// Sets the location of the template keyword.
2855
2856 SourceRange getSourceRange() const override LLVM_READONLY;
2857
2858 void Profile(llvm::FoldingSetNodeID &ID) const {
2859 Profile(ID, TemplateArgs->asArray(), getASTContext());
2860 }
2861
2862 static void Profile(llvm::FoldingSetNodeID &ID,
2863 ArrayRef<TemplateArgument> TemplateArgs,
2864 const ASTContext &Context) {
2865 ID.AddInteger(TemplateArgs.size());
2866 for (const TemplateArgument &TemplateArg : TemplateArgs)
2867 TemplateArg.Profile(ID, Context);
2868 }
2869
2870 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2871
2872 static bool classofKind(Kind K) {
2873 return K >= firstVarTemplateSpecialization &&
2874 K <= lastVarTemplateSpecialization;
2875 }
2876};
2877
2878class VarTemplatePartialSpecializationDecl
2880 /// The list of template parameters
2881 TemplateParameterList *TemplateParams = nullptr;
2882
2883 /// The variable template partial specialization from which this
2884 /// variable template partial specialization was instantiated.
2885 ///
2886 /// The boolean value will be true to indicate that this variable template
2887 /// partial specialization was specialized at this level.
2888 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2889 InstantiatedFromMember;
2890
2891 VarTemplatePartialSpecializationDecl(
2892 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2894 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2896
2897 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2898 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2899 Context),
2900 InstantiatedFromMember(nullptr, false) {}
2901
2902 void anchor() override;
2903
2904public:
2905 friend class ASTDeclReader;
2906 friend class ASTDeclWriter;
2907
2908 static VarTemplatePartialSpecializationDecl *
2909 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2911 VarTemplateDecl *SpecializedTemplate, QualType T,
2912 TypeSourceInfo *TInfo, StorageClass S,
2914
2915 static VarTemplatePartialSpecializationDecl *
2917
2918 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2920 static_cast<VarTemplateSpecializationDecl *>(
2921 this)->getMostRecentDecl());
2922 }
2923
2924 /// Get the list of template parameters
2926 return TemplateParams;
2927 }
2928
2929 /// Get the template argument list of the template parameter list.
2931 getInjectedTemplateArgs(const ASTContext &Context) const {
2933 }
2934
2935 /// \brief All associated constraints of this partial specialization,
2936 /// including the requires clause and any constraints derived from
2937 /// constrained-parameters.
2938 ///
2939 /// The constraints in the resulting list are to be treated as if in a
2940 /// conjunction ("and").
2943 TemplateParams->getAssociatedConstraints(AC);
2944 }
2945
2947 return TemplateParams->hasAssociatedConstraints();
2948 }
2949
2950 /// \brief Retrieve the member variable template partial specialization from
2951 /// which this particular variable template partial specialization was
2952 /// instantiated.
2953 ///
2954 /// \code
2955 /// template<typename T>
2956 /// struct Outer {
2957 /// template<typename U> U Inner;
2958 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2959 /// };
2960 ///
2961 /// template int* Outer<float>::Inner<int*>;
2962 /// \endcode
2963 ///
2964 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2965 /// end up instantiating the partial specialization
2966 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2967 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2968 /// \c Outer<float>::Inner<U*>, this function would return
2969 /// \c Outer<T>::Inner<U*>.
2970 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2971 const auto *First =
2973 return First->InstantiatedFromMember.getPointer();
2974 }
2975
2976 void
2977 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2979 First->InstantiatedFromMember.setPointer(PartialSpec);
2980 }
2981
2982 /// Determines whether this variable template partial specialization
2983 /// was a specialization of a member partial specialization.
2984 ///
2985 /// In the following example, the member template partial specialization
2986 /// \c X<int>::Inner<T*> is a member specialization.
2987 ///
2988 /// \code
2989 /// template<typename T>
2990 /// struct X {
2991 /// template<typename U> U Inner;
2992 /// template<typename U> U* Inner<U*> = (U*)(0);
2993 /// };
2994 ///
2995 /// template<> template<typename T>
2996 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2997 /// \endcode
2999 const auto *First =
3001 return First->InstantiatedFromMember.getInt();
3002 }
3003
3004 /// Note that this member template is a specialization.
3005 /// A partial specialization may be a member specialization even if it is not
3006 /// an instantiation of a member partial specialization.
3009 return First->InstantiatedFromMember.setInt(true);
3010 }
3011
3012 SourceRange getSourceRange() const override LLVM_READONLY;
3013
3014 void Profile(llvm::FoldingSetNodeID &ID) const {
3016 getASTContext());
3017 }
3018
3019 static void
3020 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3021 TemplateParameterList *TPL, const ASTContext &Context);
3022
3023 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3024
3025 static bool classofKind(Kind K) {
3026 return K == VarTemplatePartialSpecialization;
3027 }
3028};
3029
3030/// Declaration of a variable template.
3032protected:
3033 /// Data that is common to all of the declarations of a given
3034 /// variable template.
3036 /// The variable template specializations for this variable
3037 /// template, including explicit specializations and instantiations.
3038 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3039
3040 /// The variable template partial specializations for this variable
3041 /// template.
3042 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3044
3045 Common() = default;
3046 };
3047
3048 /// Retrieve the set of specializations of this variable template.
3049 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3050 getSpecializations() const;
3051
3052 /// Retrieve the set of partial specializations of this class
3053 /// template.
3054 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3056
3061
3062 CommonBase *newCommon(ASTContext &C) const override;
3063
3065 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3066 }
3067
3068public:
3069 friend class ASTDeclReader;
3070 friend class ASTDeclWriter;
3071
3072 /// Load any lazily-loaded specializations from the external source.
3073 void LoadLazySpecializations(bool OnlyPartial = false) const;
3074
3075 /// Get the underlying variable declarations of the template.
3077 return static_cast<VarDecl *>(TemplatedDecl);
3078 }
3079
3080 /// Returns whether this template declaration defines the primary
3081 /// variable pattern.
3085
3087
3088 /// Create a variable template node.
3091 TemplateParameterList *Params,
3092 VarDecl *Decl);
3093
3094 /// Create an empty variable template node.
3096
3097 /// Return the specialization with the provided arguments if it exists,
3098 /// otherwise return the insertion point.
3100 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3101
3102 /// Insert the specified specialization knowing that it is not already
3103 /// in. InsertPos must be obtained from findSpecialization.
3104 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3105
3112
3113 /// Retrieve the previous declaration of this variable template, or
3114 /// nullptr if no such declaration exists.
3116 return cast_or_null<VarTemplateDecl>(
3117 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3118 }
3120 return cast_or_null<VarTemplateDecl>(
3121 static_cast<const RedeclarableTemplateDecl *>(
3122 this)->getPreviousDecl());
3123 }
3124
3130 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3131 }
3132
3137
3138 /// Return the partial specialization with the provided arguments if it
3139 /// exists, otherwise return the insertion point.
3142 TemplateParameterList *TPL, void *&InsertPos);
3143
3144 /// Insert the specified partial specialization knowing that it is not
3145 /// already in. InsertPos must be obtained from findPartialSpecialization.
3147 void *InsertPos);
3148
3149 /// Retrieve the partial specializations as an ordered list.
3152
3153 /// Find a variable template partial specialization which was
3154 /// instantiated
3155 /// from the given member partial specialization.
3156 ///
3157 /// \param D a member variable template partial specialization.
3158 ///
3159 /// \returns the variable template partial specialization which was
3160 /// instantiated
3161 /// from the given member partial specialization, or nullptr if no such
3162 /// partial specialization exists.
3165
3167 using spec_range = llvm::iterator_range<spec_iterator>;
3168
3170 return spec_range(spec_begin(), spec_end());
3171 }
3172
3174 return makeSpecIterator(getSpecializations(), false);
3175 }
3176
3178 return makeSpecIterator(getSpecializations(), true);
3179 }
3180
3181 // Implement isa/cast/dyncast support
3182 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3183 static bool classofKind(Kind K) { return K == VarTemplate; }
3184};
3185
3186/// Declaration of a C++20 concept.
3187class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3188protected:
3190
3195public:
3197 DeclarationName Name,
3198 TemplateParameterList *Params,
3199 Expr *ConstraintExpr = nullptr);
3201
3203 return ConstraintExpr;
3204 }
3205
3206 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3207
3209
3210 SourceRange getSourceRange() const override LLVM_READONLY {
3211 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3212 ConstraintExpr ? ConstraintExpr->getEndLoc()
3213 : SourceLocation());
3214 }
3215
3216 bool isTypeConcept() const {
3217 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3218 }
3219
3222 }
3224 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3225 }
3226
3227 // Implement isa/cast/dyncast/etc.
3228 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3229 static bool classofKind(Kind K) { return K == Concept; }
3230
3231 friend class ASTReader;
3232 friend class ASTDeclReader;
3233 friend class ASTDeclWriter;
3234};
3235
3236// An implementation detail of ConceptSpecialicationExpr that holds the template
3237// arguments, so we can later use this to reconstitute the template arguments
3238// during constraint checking.
3239class ImplicitConceptSpecializationDecl final
3240 : public Decl,
3241 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3242 TemplateArgument> {
3243 unsigned NumTemplateArgs;
3244
3245 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3246 ArrayRef<TemplateArgument> ConvertedArgs);
3247 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3248
3249public:
3250 static ImplicitConceptSpecializationDecl *
3252 ArrayRef<TemplateArgument> ConvertedArgs);
3253 static ImplicitConceptSpecializationDecl *
3255 unsigned NumTemplateArgs);
3256
3258 return getTrailingObjects(NumTemplateArgs);
3259 }
3261
3262 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3263 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3264
3266 friend class ASTDeclReader;
3267};
3268
3269/// A template parameter object.
3270///
3271/// Template parameter objects represent values of class type used as template
3272/// arguments. There is one template parameter object for each such distinct
3273/// value used as a template argument across the program.
3274///
3275/// \code
3276/// struct A { int x, y; };
3277/// template<A> struct S;
3278/// S<A{1, 2}> s1;
3279/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3280/// \endcode
3281class TemplateParamObjectDecl : public ValueDecl,
3282 public Mergeable<TemplateParamObjectDecl>,
3283 public llvm::FoldingSetNode {
3284private:
3285 /// The value of this template parameter object.
3286 APValue Value;
3287
3288 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3289 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3290 T),
3291 Value(V) {}
3292
3293 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3294 const APValue &V);
3295 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3296 GlobalDeclID ID);
3297
3298 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3299 /// create these.
3300 friend class ASTContext;
3301 friend class ASTReader;
3302 friend class ASTDeclReader;
3303
3304public:
3305 /// Print this template parameter object in a human-readable format.
3306 void printName(llvm::raw_ostream &OS,
3307 const PrintingPolicy &Policy) const override;
3308
3309 /// Print this object as an equivalent expression.
3310 void printAsExpr(llvm::raw_ostream &OS) const;
3311 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3312
3313 /// Print this object as an initializer suitable for a variable of the
3314 /// object's type.
3315 void printAsInit(llvm::raw_ostream &OS) const;
3316 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3317
3318 const APValue &getValue() const { return Value; }
3319
3320 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3321 const APValue &V) {
3322 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3323 V.Profile(ID);
3324 }
3325 void Profile(llvm::FoldingSetNodeID &ID) {
3326 Profile(ID, getType(), getValue());
3327 }
3328
3329 TemplateParamObjectDecl *getCanonicalDecl() override {
3330 return getFirstDecl();
3331 }
3332 const TemplateParamObjectDecl *getCanonicalDecl() const {
3333 return getFirstDecl();
3334 }
3335
3336 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3337 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3338};
3339
3340/// Represents a C++26 expansion statement declaration.
3341///
3342/// This is a bit of a hack, since expansion statements shouldn't really be
3343/// 'declarations' per se (they don't declare anything). Nevertheless, we *do*
3344/// need them to be declaration *contexts*, because the DeclContext is used to
3345/// compute the 'template depth' of entities enclosed therein. In particular,
3346/// the 'template depth' is used to find instantiations of parameter variables.
3347/// A lambda enclosed within an expansion statement cannot compute its
3348/// template depth without a pointer to the enclosing expansion statement.
3349///
3350/// For the remainder of this comment, let 'expanding' an expansion statement
3351/// refer to the process of performing template substitution on its body N
3352/// times, where N is the expansion size (how this size is determined depends on
3353/// the kind of expansion statement); by contrast we may sometimes 'instantiate'
3354/// an expansion statement (because it happens to be in a template). This is
3355/// just regular template instantiation.
3356///
3357/// This node contains a 'CXXExpansionStmtPattern' as well as a
3358/// 'CXXExpansionStmtInstantiation'. These two members correspond to
3359/// distinct representations of the expansion statement: the former is used
3360/// prior to expansion and contains all the parts needed to perform expansion;
3361/// the latter holds the expanded/desugared AST nodes that result from the
3362/// expansion.
3363///
3364/// Additionally, there is a 'NonTypeTemplateParmDecl', which is a template
3365/// parameter that serves as the expansion index, e.g. during the N-th
3366/// expansion, it is set to 'N'. See the documentation of
3367/// 'CXXExpansionStmtPattern', for more information on how this is used.
3368///
3369/// After expansion, the 'CXXExpansionStmtPattern' is no longer updated and left
3370/// as-is; this also means that, if an already-expanded expansion statement is
3371/// inside a template, and that template is then instantiated, the
3372/// 'CXXExpansionStmtPattern' is *not* instantiated; only the
3373/// 'CXXExpansionStmtInstantiation' is. The latter is also what's used for
3374/// codegen and constant evaluation.
3375///
3376/// There are different kinds of expansion statements; see the comment on
3377/// 'CXXExpansionStmtPattern' for more information.
3378///
3379/// As an example, if the user writes the following expansion statement:
3380/// \verbatim
3381/// std::tuple<int, int, int> a{1, 2, 3};
3382/// template for (auto x : a) {
3383/// // ...
3384/// }
3385/// \endverbatim
3386///
3387/// The 'CXXExpansionStmtPattern' of this particular 'CXXExpansionStmtDecl'
3388/// stores, amongst other things, the declaration of the variable 'x' as well
3389/// as the expansion-initializer 'a'.
3390///
3391/// After expansion, we end up with a 'CXXExpansionStmtInstantiation' that
3392/// is *equivalent* to the AST shown below. Note that only the inner '{}' (i.e.
3393/// those marked as 'Actual "CompoundStmt"' below) are actually present as
3394/// 'CompoundStmt's in the AST; the outer braces that wrap everything do *not*
3395/// correspond to an actual 'CompoundStmt' and are implicit in the sense that we
3396/// simply push a scope when evaluating or emitting IR for a
3397/// 'CXXExpansionStmtInstantiation'.
3398///
3399/// \verbatim
3400/// { // Not actually present in the AST.
3401/// auto [__u0, __u1, __u2] = a;
3402/// { // Actual 'CompoundStmt'.
3403/// auto x = __u0;
3404/// // ...
3405/// }
3406/// { // Actual 'CompoundStmt'.
3407/// auto x = __u1;
3408/// // ...
3409/// }
3410/// { // Actual 'CompoundStmt'.
3411/// auto x = __u2;
3412/// // ...
3413/// }
3414/// }
3415/// \endverbatim
3416///
3417/// See the documentation around 'CXXExpansionStmtInstantiation' for more notes
3418/// as to why this node exist and how it is used.
3419///
3420/// \see CXXExpansionStmtPattern
3421/// \see CXXExpansionStmtInstantiation
3422class CXXExpansionStmtDecl : public Decl, public DeclContext {
3423 CXXExpansionStmtPattern *Pattern = nullptr;
3424 NonTypeTemplateParmDecl *IndexNTTP = nullptr;
3425 CXXExpansionStmtInstantiation *Instantiations = nullptr;
3426
3427 CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
3429
3430public:
3431 friend class ASTDeclReader;
3432
3433 static CXXExpansionStmtDecl *Create(ASTContext &C, DeclContext *DC,
3434 SourceLocation Loc,
3436 static CXXExpansionStmtDecl *CreateDeserialized(ASTContext &C,
3437 GlobalDeclID ID);
3438
3440 const CXXExpansionStmtPattern *getExpansionPattern() const { return Pattern; }
3442
3445 return Instantiations;
3446 }
3447
3449 Instantiations = S;
3450 }
3451
3454 return IndexNTTP;
3455 }
3456
3457 SourceRange getSourceRange() const override LLVM_READONLY;
3458
3459 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3460 static bool classofKind(Kind K) { return K == CXXExpansionStmt; }
3461};
3462
3464 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3465 return PD;
3466 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3467 return PD;
3469}
3470
3472 auto *TD = dyn_cast<TemplateDecl>(D);
3473 return TD && (isa<ClassTemplateDecl>(TD) ||
3476 [&]() {
3477 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
3478 return TTP->templateParameterKind() == TNK_Type_template;
3479 return false;
3480 }())
3481 ? TD
3482 : nullptr;
3483}
3484
3485/// Check whether the template parameter is a pack expansion, and if so,
3486/// determine the number of parameters produced by that expansion. For instance:
3487///
3488/// \code
3489/// template<typename ...Ts> struct A {
3490/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3491/// };
3492/// \endcode
3493///
3494/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3495/// is not a pack expansion, so returns an empty Optional.
3497 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3498 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3499 return Num;
3500 }
3501
3502 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3503 if (NTTP->isExpandedParameterPack())
3504 return NTTP->getNumExpansionTypes();
3505 }
3506
3507 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3508 if (TTP->isExpandedParameterPack())
3509 return TTP->getNumExpansionTemplateParameters();
3510 }
3511
3512 return std::nullopt;
3513}
3514
3515/// Internal helper used by Subst* nodes to retrieve a parameter from the
3516/// AssociatedDecl, and the template argument substituted into it, if any.
3517std::tuple<NamedDecl *, TemplateArgument>
3518getReplacedTemplateParameter(Decl *D, unsigned Index);
3519
3520/// If we have a 'templated' declaration for a template, adjust 'D' to
3521/// refer to the actual template.
3522/// If we have an implicit instantiation, adjust 'D' to refer to template.
3523const Decl &adjustDeclToTemplate(const Decl &D);
3524
3525/// Represents an explicit instantiation of a template entity in source code.
3526///
3527/// \code
3528/// template void ns::foo<int>(int); // function template
3529/// extern template struct ns::S<int>; // class template (extern)
3530/// template int ns::bar<int>; // variable template
3531/// template void ns::S<int>::method(int); // member function
3532/// \endcode
3533class ExplicitInstantiationDecl final
3534 : public Decl,
3535 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3536 NestedNameSpecifierLoc,
3537 const ASTTemplateArgumentListInfo *> {
3538 friend class ASTDeclReader;
3539 friend class ASTDeclWriter;
3540 friend TrailingObjects;
3541
3542 /// The underlying specialization (low 3 bits: TSK).
3543 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3544
3545 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3546 /// Always non-null after construction.
3547 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3548 /// qualifier, template-name, and argument locations.
3549 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3550 /// - Function / variable templates: the declared type.
3551 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3552
3553 /// Location of the 'extern' keyword (invalid if not extern template).
3554 SourceLocation ExternLoc;
3555
3556 /// Location of the entity name (e.g., 'foo' in 'template void
3557 /// ns::foo<int>(int)').
3558 SourceLocation NameLoc;
3559
3560 enum TrailingFlags : unsigned {
3561 HasQualifierFlag = 1,
3562 HasArgsAsWrittenFlag = 2,
3563 };
3564
3565 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3566 return hasTrailingQualifier() ? 1 : 0;
3567 }
3568
3569 /// For class templates / nested classes, returns the TypeLoc encoding the
3570 /// entity (TemplateSpecializationTypeLoc or TagTypeLoc). For function /
3571 /// variable templates -- where TypeSourceInfo holds the declared type
3572 /// rather than the entity -- returns std::nullopt.
3573 std::optional<TypeLoc> getClassTypeLoc() const {
3575 return std::nullopt;
3576 if (auto *TSI = TypeAndFlags.getPointer())
3577 return TSI->getTypeLoc();
3578 return std::nullopt;
3579 }
3580
3581 /// Raw TypeSourceInfo pointer, needed by the serializer.
3582 TypeSourceInfo *getRawTypeSourceInfo() const {
3583 return TypeAndFlags.getPointer();
3584 }
3585
3586 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3587 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3589 return nullptr;
3590 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3591 }
3592
3593 ExplicitInstantiationDecl(
3594 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3595 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3596 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3597 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3598
3599 ExplicitInstantiationDecl(EmptyShell Empty)
3601
3602public:
3603 static ExplicitInstantiationDecl *
3604 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3605 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3606 NestedNameSpecifierLoc QualifierLoc,
3607 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3608 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3610
3611 static ExplicitInstantiationDecl *
3612 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3613
3614 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3615
3616 SourceRange getSourceRange() const override LLVM_READONLY;
3617 SourceLocation getEndLoc() const LLVM_READONLY;
3618
3619 SourceLocation getExternLoc() const { return ExternLoc; }
3621 SourceLocation getNameLoc() const { return NameLoc; }
3622
3623 /// The tag keyword (struct/class/union) location for class templates /
3624 /// nested classes; invalid for function / variable templates.
3626
3628 return TypeAndFlags.getInt() & HasQualifierFlag;
3629 }
3631 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3632 }
3633
3634 /// Returns the qualifier regardless of where it is stored.
3635 /// For class templates / nested classes, extracted from the class TypeLoc;
3636 /// for function / variable templates, from a trailing object.
3638
3639 /// Returns the number of explicit template arguments, or std::nullopt if
3640 /// this entity has no template argument list (e.g., nested classes).
3641 std::optional<unsigned> getNumTemplateArgs() const;
3642 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3645
3646 /// The declared type (return type or variable type) for function / variable
3647 /// templates. Null for class templates and nested classes.
3649
3651 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3652 }
3653
3654 bool isExternTemplate() const { return ExternLoc.isValid(); }
3655
3656 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3657 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3658};
3659
3660} // namespace clang
3661
3662#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:480
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:223
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:223
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.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
ClassTemplateDecl * getMostRecentDecl()
spec_iterator spec_begin() const
spec_iterator spec_end() const
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
static bool classofKind(Kind K)
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
llvm::iterator_range< spec_iterator > spec_range
static bool classof(const Decl *D)
const ClassTemplateDecl * getMostRecentDecl() const
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
const ClassTemplateDecl * getCanonicalDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
SpecIterator< ClassTemplateSpecializationDecl > spec_iterator
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
void setCommonPtr(Common *C)
spec_range specializations() const
friend class TemplateDeclInstantiator
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setMemberSpecialization()
Note that this member template is a specialization.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
static bool classof(const Decl *D)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
ClassTemplateSpecializationDecl * getDefinitionOrSelf() const
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
void setDefinition(Expr *E)
Expr * getConstraintExpr() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
friend class ASTReader
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
friend class ASTDeclReader
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasDefinition() const
static bool classof(const Decl *D)
friend class ASTDeclWriter
const ConceptDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h: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:780
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL)
Definition Decl.h:800
Storage for a default argument.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
bool isSet() const
Determine whether there is a default argument for this parameter.
ArgType get() const
Get the default argument's value.
void set(ArgType Arg)
Set the default argument.
void clear()
Remove the default argument, even if it was inherited.
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getEndLoc() const LLVM_READONLY
static ExplicitInstantiationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags)
TypeSourceInfo * getTypeAsWritten() const
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:2058
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2427
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition Decl.h:2495
bool isInstantiatedFromMemberTemplate() const
Definition Decl.h:2492
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
spec_iterator spec_end() const
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D)
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
spec_range specializations() const
SpecIterator< FunctionTemplateSpecializationInfo > spec_iterator
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
bool isCompatibleWithDefinition() const
const FunctionTemplateDecl * getMostRecentDecl() const
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
void Profile(llvm::FoldingSetNodeID &ID)
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
Provides information a specialization of a member of a class template, which may be a member function...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
TemplateParamObjectDecl * getFirstDecl()
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
const DefArgStorage & getDefaultArgStorage() const
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
static bool classofKind(Kind K)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the associated-constraints of this template parameter.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
static bool classof(const Decl *D)
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
bool hasPlaceholderTypeConstraint() const
Determine whether this non-type template parameter's type has a placeholder with a type-constraint.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setPlaceholderTypeConstraint(Expr *E)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition TypeBase.h:938
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
redeclarable_base::redecl_iterator redecl_iterator
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
const RedeclarableTemplateDecl * getCanonicalDecl() const
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redeclarable_base::redecl_range redecl_range
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
static bool classof(const Decl *D)
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
static bool classofKind(Kind K)
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getNextRedeclaration() const
RedeclarableTemplateDecl * getPreviousDecl()
llvm::iterator_range< redecl_iterator > redecl_range
RedeclarableTemplateDecl * getMostRecentDecl()
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
TagTypeKind TagKind
Definition Decl.h:3856
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3947
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:3822
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:3648
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL=SourceLocation())
Definition Decl.h:3663
A container of type source information.
Definition TypeBase.h:8473
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:9338
A set of unresolved declarations.
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T)
Definition Decl.h:718
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition Decl.cpp:2242
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:2751
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
SpecIterator< VarTemplateSpecializationDecl > spec_iterator
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
spec_range specializations() const
void setMemberSpecialization()
Note that this member template is a specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplatePartialSpecializationDecl * getMostRecentDecl()
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...
static bool classof(const Decl *D)
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this variable template specialization is actually an instantiation of the given variable te...
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
void setInstantiationOf(VarTemplateDecl *TemplDecl)
Note that this variable template specialization is an instantiation of the given variable template.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this variable template specialization is an instantiation of a template (rather than an explicit s...
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
VarTemplateSpecializationDecl * getMostRecentDecl()
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
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:6038
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 ...