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 = dyn_cast<ParmDecl *>(Storage.ValueOrInherited))
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 = dyn_cast<ParmDecl *>(ValueOrInherited))
341 Storage = &Prev->getDefaultArgStorage();
342 if (const auto *C = dyn_cast<Chain *>(Storage->ValueOrInherited))
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 = dyn_cast<ParmDecl *>(ValueOrInherited))
351 return D;
352 if (const auto *C = dyn_cast<Chain *>(ValueOrInherited))
353 return C->PrevDeclWithDefaultArg;
354 return nullptr;
355 }
356
357 /// Set the default argument.
358 void set(ArgType Arg) {
359 assert(!isSet() && "default argument already set");
360 ValueOrInherited = Arg;
361 }
362
363 /// Set that the default argument was inherited from another parameter.
364 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
365 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
366 if (!isSet())
367 ValueOrInherited = InheritedFrom;
368 else if ([[maybe_unused]] auto *D =
369 dyn_cast<ParmDecl *>(ValueOrInherited)) {
370 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
371 ValueOrInherited =
372 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
373 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
374 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
375 InheritedFrom));
376 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
377 } else
378 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
379 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
380 }
381
382 /// Remove the default argument, even if it was inherited.
383 void clear() {
384 ValueOrInherited = ArgType();
385 }
386};
387
388//===----------------------------------------------------------------------===//
389// Kinds of Templates
390//===----------------------------------------------------------------------===//
391
392/// \brief The base class of all kinds of template declarations (e.g.,
393/// class, function, etc.).
394///
395/// The TemplateDecl class stores the list of template parameters and a
396/// reference to the templated scoped declaration: the underlying AST node.
397class TemplateDecl : public NamedDecl {
398 void anchor() override;
399
400protected:
401 // Construct a template decl with name, parameters, and templated element.
404
405 // Construct a template decl with the given name and parameters.
406 // Used when there is no templated element (e.g., for tt-params).
408 TemplateParameterList *Params)
409 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
410
411public:
412 friend class ASTDeclReader;
413 friend class ASTDeclWriter;
414
415 /// Get the list of template parameters
419
420 /// \brief Get the total constraint-expression associated with this template,
421 /// including constraint-expressions derived from the requires-clause,
422 /// trailing requires-clause (for functions and methods) and constrained
423 /// template parameters.
426
427 bool hasAssociatedConstraints() const;
428
429 /// Get the underlying, templated declaration.
431
432 // Should a specialization behave like an alias for another type.
433 bool isTypeAlias() const;
434
435 // Implement isa/cast/dyncast/etc.
436 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
437
438 static bool classofKind(Kind K) {
439 return K >= firstTemplate && K <= lastTemplate;
440 }
441
442 SourceRange getSourceRange() const override LLVM_READONLY {
443 return SourceRange(getTemplateParameters()->getTemplateLoc(),
444 TemplatedDecl->getSourceRange().getEnd());
445 }
446
447protected:
450
451public:
453 TemplateParams = TParams;
454 }
455
456 /// Initialize the underlying templated declaration.
457 void init(NamedDecl *NewTemplatedDecl) {
458 if (TemplatedDecl)
459 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
460 else
461 TemplatedDecl = NewTemplatedDecl;
462 }
463};
464
465/// Provides information about a function template specialization,
466/// which is a FunctionDecl that has been explicitly specialization or
467/// instantiated from a function template.
468class FunctionTemplateSpecializationInfo final
469 : public llvm::FoldingSetNode,
470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
471 MemberSpecializationInfo *> {
472 /// The function template specialization that this structure describes and a
473 /// flag indicating if the function is a member specialization.
474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
475
476 /// The function template from which this function template
477 /// specialization was generated.
478 ///
479 /// The two bits contain the top 4 values of TemplateSpecializationKind.
480 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
481
482public:
483 /// The template arguments used to produce the function template
484 /// specialization from the function template.
486
487 /// The template arguments as written in the sources, if provided.
488 /// FIXME: Normally null; tail-allocate this.
490
491 /// The point at which this function template specialization was
492 /// first instantiated.
494
495private:
496 FunctionTemplateSpecializationInfo(
497 FunctionDecl *FD, FunctionTemplateDecl *Template,
499 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
501 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
502 TemplateArguments(TemplateArgs),
503 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
505 if (MSInfo)
506 getTrailingObjects()[0] = MSInfo;
507 }
508
509 size_t numTrailingObjects() const { return Function.getInt(); }
510
511public:
513
514 static FunctionTemplateSpecializationInfo *
517 const TemplateArgumentListInfo *TemplateArgsAsWritten,
519
520 /// Retrieve the declaration of the function template specialization.
521 FunctionDecl *getFunction() const { return Function.getPointer(); }
522
523 /// Retrieve the template from which this function was specialized.
524 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
525
526 /// Determine what kind of template specialization this is.
528 return (TemplateSpecializationKind)(Template.getInt() + 1);
529 }
530
534
535 /// True if this declaration is an explicit specialization,
536 /// explicit instantiation declaration, or explicit instantiation
537 /// definition.
542
543 /// Set the template specialization kind.
545 assert(TSK != TSK_Undeclared &&
546 "Cannot encode TSK_Undeclared for a function template specialization");
547 Template.setInt(TSK - 1);
548 }
549
550 /// Retrieve the first point of instantiation of this function
551 /// template specialization.
552 ///
553 /// The point of instantiation may be an invalid source location if this
554 /// function has yet to be instantiated.
558
559 /// Set the (first) point of instantiation of this function template
560 /// specialization.
564
565 /// Get the specialization info if this function template specialization is
566 /// also a member specialization:
567 ///
568 /// \code
569 /// template<typename> struct A {
570 /// template<typename> void f();
571 /// template<> void f<int>();
572 /// };
573 /// \endcode
574 ///
575 /// Here, A<int>::f<int> is a function template specialization that is
576 /// an explicit specialization of A<int>::f, but it's also a member
577 /// specialization (an implicit instantiation in this case) of A::f<int>.
578 /// Further:
579 ///
580 /// \code
581 /// template<> template<> void A<int>::f<int>() {}
582 /// \endcode
583 ///
584 /// ... declares a function template specialization that is an explicit
585 /// specialization of A<int>::f, and is also an explicit member
586 /// specialization of A::f<int>.
587 ///
588 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
589 /// need not be the same as that returned by getTemplateSpecializationKind(),
590 /// and represents the relationship between the function and the class-scope
591 /// explicit specialization in the original templated class -- whereas our
592 /// TemplateSpecializationKind represents the relationship between the
593 /// function and the function template, and should always be
594 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
596 return numTrailingObjects() ? getTrailingObjects()[0] : nullptr;
597 }
598
599 void Profile(llvm::FoldingSetNodeID &ID) {
600 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
601 }
602
603 static void
604 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
605 const ASTContext &Context) {
606 ID.AddInteger(TemplateArgs.size());
607 for (const TemplateArgument &TemplateArg : TemplateArgs)
608 TemplateArg.Profile(ID, Context);
609 }
610};
611
612/// Provides information a specialization of a member of a class
613/// template, which may be a member function, static data member,
614/// member class or member enumeration.
616 // The member declaration from which this member was instantiated, and the
617 // manner in which the instantiation occurred (in the lower two bits).
618 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
619
620 // The point at which this member was first instantiated.
621 SourceLocation PointOfInstantiation;
622
623public:
624 explicit
627 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
628 assert(TSK != TSK_Undeclared &&
629 "Cannot encode undeclared template specializations for members");
630 }
631
632 /// Retrieve the member declaration from which this member was
633 /// instantiated.
634 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
635
636 /// Determine what kind of template specialization this is.
638 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
639 }
640
644
645 /// Set the template specialization kind.
647 assert(TSK != TSK_Undeclared &&
648 "Cannot encode undeclared template specializations for members");
649 MemberAndTSK.setInt(TSK - 1);
650 }
651
652 /// Retrieve the first point of instantiation of this member.
653 /// If the point of instantiation is an invalid location, then this member
654 /// has not yet been instantiated.
656 return PointOfInstantiation;
657 }
658
659 /// Set the first point of instantiation.
661 PointOfInstantiation = POI;
662 }
663};
664
665/// Provides information about a dependent function-template
666/// specialization declaration.
667///
668/// This is used for function templates explicit specializations declared
669/// within class templates:
670///
671/// \code
672/// template<typename> struct A {
673/// template<typename> void f();
674/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
675/// };
676/// \endcode
677///
678/// As well as dependent friend declarations naming function template
679/// specializations declared within class templates:
680///
681/// \code
682/// template <class T> void foo(T);
683/// template <class T> class A {
684/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
685/// };
686/// \endcode
687class DependentFunctionTemplateSpecializationInfo final
688 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
689 FunctionTemplateDecl *> {
690 friend TrailingObjects;
691
692 /// The number of candidates for the primary template.
693 unsigned NumCandidates;
694
695 DependentFunctionTemplateSpecializationInfo(
696 const UnresolvedSetImpl &Candidates,
697 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
698
699public:
700 /// The template arguments as written in the sources, if provided.
702
703 static DependentFunctionTemplateSpecializationInfo *
704 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
705 const TemplateArgumentListInfo *TemplateArgs);
706
707 /// Returns the candidates for the primary function template.
709 return getTrailingObjects(NumCandidates);
710 }
711};
712
713/// Declaration of a redeclarable template.
715 public Redeclarable<RedeclarableTemplateDecl>
716{
717 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
718
720 return getNextRedeclaration();
721 }
722
724 return getPreviousDecl();
725 }
726
728 return getMostRecentDecl();
729 }
730
731 void anchor() override;
732
733protected:
734 template <typename EntryType> struct SpecEntryTraits {
735 using DeclType = EntryType;
736
737 static DeclType *getDecl(EntryType *D) {
738 return D;
739 }
740
742 return D->getTemplateArgs().asArray();
743 }
744 };
745
746 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
747 typename DeclType = typename SETraits::DeclType>
749 : llvm::iterator_adaptor_base<
750 SpecIterator<EntryType, SETraits, DeclType>,
751 typename llvm::FoldingSetVector<EntryType>::iterator,
752 typename std::iterator_traits<typename llvm::FoldingSetVector<
753 EntryType>::iterator>::iterator_category,
754 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
755 SpecIterator() = default;
756 explicit SpecIterator(
757 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
758 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
759
760 DeclType *operator*() const {
761 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
762 }
763
764 DeclType *operator->() const { return **this; }
765 };
766
767 template <typename EntryType>
768 static SpecIterator<EntryType>
769 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
770 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
771 }
772
773 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
774
776 TemplateParameterList *TPL = nullptr) const;
777
778 template <class EntryType, typename... ProfileArguments>
780 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
781 llvm::FoldingSetInsertToken &InsertToken,
782 ProfileArguments... ProfileArgs);
783
784 template <class EntryType, typename... ProfileArguments>
786 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
787 llvm::FoldingSetInsertToken &InsertToken,
788 ProfileArguments... ProfileArgs);
789
790 template <class Derived, class EntryType>
791 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
792 EntryType *Entry,
793 llvm::FoldingSetInsertToken InsertToken);
794
795 struct CommonBase {
797
798 /// The template from which this was most
799 /// directly instantiated (or null).
800 ///
801 /// The boolean value indicates whether this template
802 /// was explicitly specialized.
803 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
805 };
806
807 /// Pointer to the common data shared by all declarations of this
808 /// template.
809 mutable CommonBase *Common = nullptr;
810
811 /// Retrieves the "common" pointer shared by all (re-)declarations of
812 /// the same template. Calling this routine may implicitly allocate memory
813 /// for the common pointer.
814 CommonBase *getCommonPtr() const;
815
816 virtual CommonBase *newCommon(ASTContext &C) const = 0;
817
818 // Construct a template decl with name, parameters, and templated element.
822 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
823
824public:
825 friend class ASTDeclReader;
826 friend class ASTDeclWriter;
827 friend class ASTReader;
828
829 /// Retrieves the canonical declaration of this template.
831 return getFirstDecl();
832 }
834 return getFirstDecl();
835 }
836
837 /// Determines whether this template was a specialization of a
838 /// member template.
839 ///
840 /// In the following example, the function template \c X<int>::f and the
841 /// member template \c X<int>::Inner are member specializations.
842 ///
843 /// \code
844 /// template<typename T>
845 /// struct X {
846 /// template<typename U> void f(T, U);
847 /// template<typename U> struct Inner;
848 /// };
849 ///
850 /// template<> template<typename T>
851 /// void X<int>::f(int, T);
852 /// template<> template<typename T>
853 /// struct X<int>::Inner { /* ... */ };
854 /// \endcode
856 return getCommonPtr()->InstantiatedFromMember.getInt();
857 }
858
859 /// Note that this member template is a specialization.
861 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
862 "Only member templates can be member template specializations");
863 getCommonPtr()->InstantiatedFromMember.setInt(true);
864 }
865
866 /// Retrieve the member template from which this template was
867 /// instantiated, or nullptr if this template was not instantiated from a
868 /// member template.
869 ///
870 /// A template is instantiated from a member template when the member
871 /// template itself is part of a class template (or member thereof). For
872 /// example, given
873 ///
874 /// \code
875 /// template<typename T>
876 /// struct X {
877 /// template<typename U> void f(T, U);
878 /// };
879 ///
880 /// void test(X<int> x) {
881 /// x.f(1, 'a');
882 /// };
883 /// \endcode
884 ///
885 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
886 /// template
887 ///
888 /// \code
889 /// template<typename U> void X<int>::f(int, U);
890 /// \endcode
891 ///
892 /// which was itself created during the instantiation of \c X<int>. Calling
893 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
894 /// retrieve the FunctionTemplateDecl for the original template \c f within
895 /// the class template \c X<T>, i.e.,
896 ///
897 /// \code
898 /// template<typename T>
899 /// template<typename U>
900 /// void X<T>::f(T, U);
901 /// \endcode
905
907 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
908 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
909 }
910
911 /// Retrieve the "injected" template arguments that correspond to the
912 /// template parameters of this template.
913 ///
914 /// Although the C++ standard has no notion of the "injected" template
915 /// arguments for a template, the notion is convenient when
916 /// we need to perform substitutions inside the definition of a template.
918 getInjectedTemplateArgs(const ASTContext &Context) const {
920 }
921
923 using redecl_iterator = redeclarable_base::redecl_iterator;
924
931
932 // Implement isa/cast/dyncast/etc.
933 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
934
935 static bool classofKind(Kind K) {
936 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
937 }
938};
939
940template <> struct RedeclarableTemplateDecl::
941SpecEntryTraits<FunctionTemplateSpecializationInfo> {
943
947
952};
953
954/// Declaration of a template function.
956protected:
957 friend class FunctionDecl;
958
959 /// Data that is common to all of the declarations of a given
960 /// function template.
962 /// The function template specializations for this function
963 /// template, including explicit specializations and instantiations.
964 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
965
966 Common() = default;
967 };
968
974
975 CommonBase *newCommon(ASTContext &C) const override;
976
978 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
979 }
980
981 /// Retrieve the set of function template specializations of this
982 /// function template.
983 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
984 getSpecializations() const;
985
986 /// Add a specialization of this function template.
987 ///
988 /// \param InsertToken Insert token, must have been retrieved by an earlier
989 /// call to findSpecialization().
991 llvm::FoldingSetInsertToken InsertToken);
992
993public:
994 friend class ASTDeclReader;
995 friend class ASTDeclWriter;
996
997 /// Load any lazily-loaded specializations from the external source.
998 void LoadLazySpecializations() const;
999
1000 /// Get the underlying function declaration of the template.
1002 return static_cast<FunctionDecl *>(TemplatedDecl);
1003 }
1004
1005 /// Returns whether this template declaration defines the primary
1006 /// pattern.
1010
1015
1016 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1017 // except this is per declaration, while the redeclarable field is
1018 // per chain. This indicates a template redeclaration which
1019 // is compatible with the definition, in the non-trivial case
1020 // where this is not already a definition.
1021 // This is only really needed for instantiating the definition of friend
1022 // function templates, which can have redeclarations in different template
1023 // contexts.
1024 // The bit is actually stored in the FunctionDecl for space efficiency
1025 // reasons.
1030
1031 /// Return the specialization with the provided arguments if it exists,
1032 /// otherwise return the insertion point.
1034 llvm::FoldingSetInsertToken &InsertToken);
1035
1044
1045 /// Retrieve the previous declaration of this function template, or
1046 /// nullptr if no such declaration exists.
1048 return cast_or_null<FunctionTemplateDecl>(
1049 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1050 }
1052 return cast_or_null<FunctionTemplateDecl>(
1053 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1054 }
1055
1062 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1063 }
1064
1066 return cast_or_null<FunctionTemplateDecl>(
1068 }
1069
1071 using spec_range = llvm::iterator_range<spec_iterator>;
1072
1074 return spec_range(spec_begin(), spec_end());
1075 }
1076
1078 return makeSpecIterator(getSpecializations(), false);
1079 }
1080
1082 return makeSpecIterator(getSpecializations(), true);
1083 }
1084
1085 /// Return whether this function template is an abbreviated function template,
1086 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1087 bool isAbbreviated() const {
1088 // Since the invented template parameters generated from 'auto' parameters
1089 // are either appended to the end of the explicit template parameter list or
1090 // form a new template parameter list, we can simply observe the last
1091 // parameter to determine if such a thing happened.
1093 return TPL->getParam(TPL->size() - 1)->isImplicit();
1094 }
1095
1096 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1098
1099 /// Create a function template node.
1102 DeclarationName Name,
1103 TemplateParameterList *Params,
1104 NamedDecl *Decl);
1105
1106 /// Create an empty function template node.
1108 GlobalDeclID ID);
1109
1110 // Implement isa/cast/dyncast support
1111 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1112 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1113};
1114
1115//===----------------------------------------------------------------------===//
1116// Kinds of Template Parameters
1117//===----------------------------------------------------------------------===//
1118
1119/// Defines the position of a template parameter within a template
1120/// parameter list.
1121///
1122/// Because template parameter can be listed
1123/// sequentially for out-of-line template members, each template parameter is
1124/// given a Depth - the nesting of template parameter scopes - and a Position -
1125/// the occurrence within the parameter list.
1126/// This class is inheritedly privately by different kinds of template
1127/// parameters and is not part of the Decl hierarchy. Just a facility.
1129protected:
1130 enum { DepthWidth = 20, PositionWidth = 12 };
1131 unsigned Depth : DepthWidth;
1133
1134 TemplateParmPosition(int D, int P) {
1135 setDepth(D);
1136 setPosition(P);
1137 }
1138
1139public:
1141
1142 /// Get the nesting depth of the template parameter.
1143 unsigned getDepth() const { return Depth; }
1144 void setDepth(int D) {
1145 assert(D >= 0 && "The depth cannot be negative");
1146 assert(D < (1 << DepthWidth) && "The depth is too large");
1147 Depth = D;
1148 }
1149
1150 /// Get the position of the template parameter within its parameter list.
1151 unsigned getPosition() const { return Position; }
1152 void setPosition(int P) {
1153 assert(P >= 0 && "The position cannot be negative");
1154 assert(P < (1 << PositionWidth) && "The position is too large");
1155 Position = P;
1156 }
1157
1158 /// Get the index of the template parameter within its parameter list.
1159 unsigned getIndex() const { return Position; }
1160};
1161
1162/// Declaration of a template type parameter.
1163///
1164/// For example, "T" in
1165/// \code
1166/// template<typename T> class vector;
1167/// \endcode
1168class TemplateTypeParmDecl final : public TypeDecl,
1169 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1170 /// Sema creates these on the stack during auto type deduction.
1171 friend class Sema;
1172 friend TrailingObjects;
1173 friend class ASTDeclReader;
1174
1175 /// Whether this template type parameter was declaration with
1176 /// the 'typename' keyword.
1177 ///
1178 /// If false, it was declared with the 'class' keyword.
1179 bool Typename : 1;
1180
1181 /// Whether this template type parameter has a type-constraint construct.
1182 bool HasTypeConstraint : 1;
1183
1184 /// Whether the type constraint has been initialized. This can be false if the
1185 /// constraint was not initialized yet or if there was an error forming the
1186 /// type constraint.
1187 bool TypeConstraintInitialized : 1;
1188
1189 /// The number of type parameters in an expanded parameter pack, if any.
1190 UnsignedOrNone NumExpanded = std::nullopt;
1191
1192 /// The default template argument, if any.
1193 using DefArgStorage =
1195 DefArgStorage DefaultArgument;
1196
1197 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1198 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1199 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1200 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1201 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1202 NumExpanded(NumExpanded) {}
1203
1204public:
1205 static TemplateTypeParmDecl *
1206 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1207 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1208 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1209 UnsignedOrNone NumExpanded = std::nullopt);
1211 GlobalDeclID ID);
1213 GlobalDeclID ID,
1214 bool HasTypeConstraint);
1215
1216 /// Whether this template type parameter was declared with
1217 /// the 'typename' keyword.
1218 ///
1219 /// If not, it was either declared with the 'class' keyword or with a
1220 /// type-constraint (see hasTypeConstraint()).
1222 return Typename && !HasTypeConstraint;
1223 }
1224
1225 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1226
1227 /// Determine whether this template parameter has a default
1228 /// argument.
1229 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1230
1231 /// Retrieve the default argument, if any.
1233 static const TemplateArgumentLoc NoneLoc;
1234 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1235 }
1236
1237 /// Retrieves the location of the default argument declaration.
1239
1240 /// Determines whether the default argument was inherited
1241 /// from a previous declaration of this template.
1243 return DefaultArgument.isInherited();
1244 }
1245
1246 /// Set the default argument for this template parameter.
1247 void setDefaultArgument(const ASTContext &C,
1248 const TemplateArgumentLoc &DefArg);
1249
1250 /// Set that this default argument was inherited from another
1251 /// parameter.
1253 TemplateTypeParmDecl *Prev) {
1254 DefaultArgument.setInherited(C, Prev);
1255 }
1256
1257 /// Removes the default argument of this template parameter.
1259 DefaultArgument.clear();
1260 }
1261
1262 /// Set whether this template type parameter was declared with
1263 /// the 'typename' or 'class' keyword.
1264 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1265
1266 /// Retrieve the depth of the template parameter.
1267 unsigned getDepth() const;
1268
1269 /// Retrieve the index of the template parameter.
1270 unsigned getIndex() const;
1271
1272 /// Returns whether this is a parameter pack.
1273 bool isParameterPack() const;
1274
1275 /// Whether this parameter pack is a pack expansion.
1276 ///
1277 /// A template type template parameter pack can be a pack expansion if its
1278 /// type-constraint contains an unexpanded parameter pack.
1279 bool isPackExpansion() const {
1280 if (!isParameterPack())
1281 return false;
1282 if (const TypeConstraint *TC = getTypeConstraint())
1283 if (TC->hasExplicitTemplateArgs())
1284 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1285 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1286 return true;
1287 return false;
1288 }
1289
1290 /// Whether this parameter is a template type parameter pack that has a known
1291 /// list of different type-constraints at different positions.
1292 ///
1293 /// A parameter pack is an expanded parameter pack when the original
1294 /// parameter pack's type-constraint was itself a pack expansion, and that
1295 /// expansion has already been expanded. For example, given:
1296 ///
1297 /// \code
1298 /// template<typename ...Types>
1299 /// struct X {
1300 /// template<convertible_to<Types> ...Convertibles>
1301 /// struct Y { /* ... */ };
1302 /// };
1303 /// \endcode
1304 ///
1305 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1306 /// its type-constraint. When \c Types is supplied with template arguments by
1307 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1308 /// expanded parameter pack. For example, instantiating
1309 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1310 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1311 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1312 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1313
1314 /// Returns the type constraint associated with this template parameter (if
1315 /// any).
1317 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1318 }
1319
1321 Expr *ImmediatelyDeclaredConstraint,
1322 UnsignedOrNone ArgPackSubstIndex);
1323
1324 /// Determine whether this template parameter has a type-constraint.
1325 bool hasTypeConstraint() const {
1326 return HasTypeConstraint;
1327 }
1328
1329 /// \brief Get the associated-constraints of this template parameter.
1330 /// This will either be the immediately-introduced constraint or empty.
1331 ///
1332 /// Use this instead of getTypeConstraint for concepts APIs that
1333 /// accept an ArrayRef of constraint expressions.
1336 if (HasTypeConstraint)
1337 AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1338 getTypeConstraint()->getArgPackSubstIndex());
1339 }
1340
1341 SourceRange getSourceRange() const override LLVM_READONLY;
1342
1343 // Implement isa/cast/dyncast/etc.
1344 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1345 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1346};
1347
1348/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1349/// e.g., "Size" in
1350/// @code
1351/// template<int Size> class array { };
1352/// @endcode
1353class NonTypeTemplateParmDecl final
1354 : public DeclaratorDecl,
1355 protected TemplateParmPosition,
1356 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1357 std::pair<QualType, TypeSourceInfo *>,
1358 Expr *> {
1359 friend class ASTDeclReader;
1360 friend TrailingObjects;
1361
1362 /// The default template argument, if any, and whether or not
1363 /// it was inherited.
1364 using DefArgStorage =
1366 DefArgStorage DefaultArgument;
1367
1368 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1369 // down here to save memory.
1370
1371 /// Whether this non-type template parameter is a parameter pack.
1372 bool ParameterPack;
1373
1374 /// Whether this non-type template parameter is an "expanded"
1375 /// parameter pack, meaning that its type is a pack expansion and we
1376 /// already know the set of types that expansion expands to.
1377 bool ExpandedParameterPack = false;
1378
1379 /// The number of types in an expanded parameter pack.
1380 unsigned NumExpandedTypes = 0;
1381
1382 size_t numTrailingObjects(
1383 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1384 return NumExpandedTypes;
1385 }
1386
1388 SourceLocation IdLoc, int D, int P,
1389 const IdentifierInfo *Id, QualType T,
1390 bool ParameterPack, TypeSourceInfo *TInfo)
1391 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1392 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1393
1394 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1395 SourceLocation IdLoc, int D, int P,
1396 const IdentifierInfo *Id, QualType T,
1397 TypeSourceInfo *TInfo,
1398 ArrayRef<QualType> ExpandedTypes,
1399 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1400
1401public:
1402 static NonTypeTemplateParmDecl *
1403 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1404 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1405 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1406
1407 static NonTypeTemplateParmDecl *
1408 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1409 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1410 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1411 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1412
1413 static NonTypeTemplateParmDecl *
1414 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1415 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1416 GlobalDeclID ID,
1417 unsigned NumExpandedTypes,
1418 bool HasTypeConstraint);
1419
1425
1426 SourceRange getSourceRange() const override LLVM_READONLY;
1427
1428 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1429
1430 /// Determine whether this template parameter has a default
1431 /// argument.
1432 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1433
1434 /// Retrieve the default argument, if any.
1436 static const TemplateArgumentLoc NoneLoc;
1437 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1438 }
1439
1440 /// Retrieve the location of the default argument, if any.
1442
1443 /// Determines whether the default argument was inherited
1444 /// from a previous declaration of this template.
1446 return DefaultArgument.isInherited();
1447 }
1448
1449 /// Set the default argument for this template parameter, and
1450 /// whether that default argument was inherited from another
1451 /// declaration.
1452 void setDefaultArgument(const ASTContext &C,
1453 const TemplateArgumentLoc &DefArg);
1455 NonTypeTemplateParmDecl *Parm) {
1456 DefaultArgument.setInherited(C, Parm);
1457 }
1458
1459 /// Removes the default argument of this template parameter.
1460 void removeDefaultArgument() { DefaultArgument.clear(); }
1461
1462 /// Whether this parameter is a non-type template parameter pack.
1463 ///
1464 /// If the parameter is a parameter pack, the type may be a
1465 /// \c PackExpansionType. In the following example, the \c Dims parameter
1466 /// is a parameter pack (whose type is 'unsigned').
1467 ///
1468 /// \code
1469 /// template<typename T, unsigned ...Dims> struct multi_array;
1470 /// \endcode
1471 bool isParameterPack() const { return ParameterPack; }
1472
1473 /// Whether this parameter pack is a pack expansion.
1474 ///
1475 /// A non-type template parameter pack is a pack expansion if its type
1476 /// contains an unexpanded parameter pack. In this case, we will have
1477 /// built a PackExpansionType wrapping the type.
1478 bool isPackExpansion() const {
1479 return ParameterPack && getType()->getAs<PackExpansionType>();
1480 }
1481
1482 /// Whether this parameter is a non-type template parameter pack
1483 /// that has a known list of different types at different positions.
1484 ///
1485 /// A parameter pack is an expanded parameter pack when the original
1486 /// parameter pack's type was itself a pack expansion, and that expansion
1487 /// has already been expanded. For example, given:
1488 ///
1489 /// \code
1490 /// template<typename ...Types>
1491 /// struct X {
1492 /// template<Types ...Values>
1493 /// struct Y { /* ... */ };
1494 /// };
1495 /// \endcode
1496 ///
1497 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1498 /// which expands \c Types. When \c Types is supplied with template arguments
1499 /// by instantiating \c X, the instantiation of \c Values becomes an
1500 /// expanded parameter pack. For example, instantiating
1501 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1502 /// pack with expansion types \c int and \c unsigned int.
1503 ///
1504 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1505 /// return the expansion types.
1506 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1507
1508 /// Retrieves the number of expansion types in an expanded parameter
1509 /// pack.
1510 unsigned getNumExpansionTypes() const {
1511 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1512 return NumExpandedTypes;
1513 }
1514
1515 /// Retrieve a particular expansion type within an expanded parameter
1516 /// pack.
1517 QualType getExpansionType(unsigned I) const {
1518 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1519 auto TypesAndInfos =
1520 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1521 return TypesAndInfos[I].first;
1522 }
1523
1524 /// Retrieve a particular expansion type source info within an
1525 /// expanded parameter pack.
1527 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1528 auto TypesAndInfos =
1529 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1530 return TypesAndInfos[I].second;
1531 }
1532
1533 /// Return the constraint introduced by the placeholder type of this non-type
1534 /// template parameter (if any).
1536 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1537 nullptr;
1538 }
1539
1541 *getTrailingObjects<Expr *>() = E;
1542 }
1543
1544 /// Determine whether this non-type template parameter's type has a
1545 /// placeholder with a type-constraint.
1547 auto *AT = getType()->getContainedAutoType();
1548 return AT && AT->isConstrained();
1549 }
1550
1551 /// \brief Get the associated-constraints of this template parameter.
1552 /// This will either be a vector of size 1 containing the immediately-declared
1553 /// constraint introduced by the placeholder type, or an empty vector.
1554 ///
1555 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1556 /// concepts APIs that accept an ArrayRef of constraint expressions.
1560 AC.emplace_back(E);
1561 }
1562
1563 // Implement isa/cast/dyncast/etc.
1564 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1565 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1566};
1567
1568/// TemplateTemplateParmDecl - Declares a template template parameter,
1569/// e.g., "T" in
1570/// @code
1571/// template <template <typename> class T> class container { };
1572/// @endcode
1573/// A template template parameter is a TemplateDecl because it defines the
1574/// name of a template and the template parameters allowable for substitution.
1575class TemplateTemplateParmDecl final
1576 : public TemplateDecl,
1577 protected TemplateParmPosition,
1578 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1579 TemplateParameterList *> {
1580 /// The default template argument, if any.
1581 using DefArgStorage =
1583 DefArgStorage DefaultArgument;
1584
1585 LLVM_PREFERRED_TYPE(TemplateNameKind)
1586 unsigned ParameterKind : 3;
1587
1588 /// Whether this template template parameter was declaration with
1589 /// the 'typename' keyword.
1590 ///
1591 /// If false, it was declared with the 'class' keyword.
1592 LLVM_PREFERRED_TYPE(bool)
1593 unsigned Typename : 1;
1594
1595 /// Whether this parameter is a parameter pack.
1596 LLVM_PREFERRED_TYPE(bool)
1597 unsigned ParameterPack : 1;
1598
1599 /// Whether this template template parameter is an "expanded"
1600 /// parameter pack, meaning that it is a pack expansion and we
1601 /// already know the set of template parameters that expansion expands to.
1602 LLVM_PREFERRED_TYPE(bool)
1603 unsigned ExpandedParameterPack : 1;
1604
1605 /// The number of parameters in an expanded parameter pack.
1606 unsigned NumExpandedParams = 0;
1607
1608 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1609 bool ParameterPack, IdentifierInfo *Id,
1610 TemplateNameKind ParameterKind, bool Typename,
1611 TemplateParameterList *Params)
1612 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1613 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1614 Typename(Typename), ParameterPack(ParameterPack),
1615 ExpandedParameterPack(false) {}
1616
1617 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1618 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1619 bool Typename, TemplateParameterList *Params,
1621
1622 void anchor() override;
1623
1624public:
1625 friend class ASTDeclReader;
1626 friend class ASTDeclWriter;
1628
1629 static TemplateTemplateParmDecl *
1630 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1631 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1632 bool Typename, TemplateParameterList *Params);
1633
1634 static TemplateTemplateParmDecl *
1635 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1636 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1637 TemplateParameterList *Params,
1639
1640 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1641 GlobalDeclID ID);
1642 static TemplateTemplateParmDecl *
1643 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1644
1650
1651 /// Whether this template template parameter was declared with
1652 /// the 'typename' keyword.
1653 bool wasDeclaredWithTypename() const { return Typename; }
1654
1655 /// Set whether this template template parameter was declared with
1656 /// the 'typename' or 'class' keyword.
1657 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1658
1659 /// Whether this template template parameter is a template
1660 /// parameter pack.
1661 ///
1662 /// \code
1663 /// template<template <class T> ...MetaFunctions> struct Apply;
1664 /// \endcode
1665 bool isParameterPack() const { return ParameterPack; }
1666
1667 /// Whether this parameter pack is a pack expansion.
1668 ///
1669 /// A template template parameter pack is a pack expansion if its template
1670 /// parameter list contains an unexpanded parameter pack.
1671 bool isPackExpansion() const {
1672 return ParameterPack &&
1674 }
1675
1676 /// Whether this parameter is a template template parameter pack that
1677 /// has a known list of different template parameter lists at different
1678 /// positions.
1679 ///
1680 /// A parameter pack is an expanded parameter pack when the original parameter
1681 /// pack's template parameter list was itself a pack expansion, and that
1682 /// expansion has already been expanded. For exampe, given:
1683 ///
1684 /// \code
1685 /// template<typename...Types> struct Outer {
1686 /// template<template<Types> class...Templates> struct Inner;
1687 /// };
1688 /// \endcode
1689 ///
1690 /// The parameter pack \c Templates is a pack expansion, which expands the
1691 /// pack \c Types. When \c Types is supplied with template arguments by
1692 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1693 /// parameter pack.
1694 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1695
1696 /// Retrieves the number of expansion template parameters in
1697 /// an expanded parameter pack.
1699 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1700 return NumExpandedParams;
1701 }
1702
1703 /// Retrieve a particular expansion type within an expanded parameter
1704 /// pack.
1706 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1707 return getTrailingObjects()[I];
1708 }
1709
1710 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1711
1712 /// Determine whether this template parameter has a default
1713 /// argument.
1714 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1715
1716 /// Retrieve the default argument, if any.
1718 static const TemplateArgumentLoc NoneLoc;
1719 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1720 }
1721
1722 /// Retrieve the location of the default argument, if any.
1724
1725 /// Determines whether the default argument was inherited
1726 /// from a previous declaration of this template.
1728 return DefaultArgument.isInherited();
1729 }
1730
1731 /// Set the default argument for this template parameter, and
1732 /// whether that default argument was inherited from another
1733 /// declaration.
1734 void setDefaultArgument(const ASTContext &C,
1735 const TemplateArgumentLoc &DefArg);
1737 TemplateTemplateParmDecl *Prev) {
1738 DefaultArgument.setInherited(C, Prev);
1739 }
1740
1741 /// Removes the default argument of this template parameter.
1742 void removeDefaultArgument() { DefaultArgument.clear(); }
1743
1744 SourceRange getSourceRange() const override LLVM_READONLY {
1748 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1749 }
1750
1752 return static_cast<TemplateNameKind>(ParameterKind);
1753 }
1754
1760
1761 // Implement isa/cast/dyncast/etc.
1762 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1763 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1764};
1765
1766/// Represents the builtin template declaration which is used to
1767/// implement __make_integer_seq and other builtin templates. It serves
1768/// no real purpose beyond existing as a place to hold template parameters.
1769class BuiltinTemplateDecl : public TemplateDecl {
1771
1772 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1774
1775 void anchor() override;
1776
1777public:
1778 // Implement isa/cast/dyncast support
1779 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1780 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1781
1782 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1783 DeclarationName Name,
1784 BuiltinTemplateKind BTK) {
1785 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1786 }
1787
1788 SourceRange getSourceRange() const override LLVM_READONLY {
1789 return {};
1790 }
1791
1793
1794 bool isPackProducingBuiltinTemplate() const;
1795};
1797
1798/// Provides information about an explicit instantiation of a variable or class
1799/// template.
1801 /// The template arguments as written..
1803
1804 /// The location of the extern keyword.
1806
1807 /// The location of the template keyword.
1809
1811};
1812
1814 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1816
1817/// Represents a class template specialization, which refers to
1818/// a class template with a given set of template arguments.
1819///
1820/// Class template specializations represent both explicit
1821/// specialization of class templates, as in the example below, and
1822/// implicit instantiations of class templates.
1823///
1824/// \code
1825/// template<typename T> class array;
1826///
1827/// template<>
1828/// class array<bool> { }; // class template specialization array<bool>
1829/// \endcode
1831 public llvm::FoldingSetNode {
1832 /// Structure that stores information about a class template
1833 /// specialization that was instantiated from a class template partial
1834 /// specialization.
1835 struct SpecializedPartialSpecialization {
1836 /// The class template partial specialization from which this
1837 /// class template specialization was instantiated.
1838 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1839
1840 /// The template argument list deduced for the class template
1841 /// partial specialization itself.
1842 const TemplateArgumentList *TemplateArgs;
1843 };
1844
1845 /// The template that this specialization specializes
1846 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1847 SpecializedTemplate;
1848
1849 /// Further info for explicit template specialization/instantiation.
1850 /// Does not apply to implicit specializations.
1851 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1852
1853 /// The template arguments used to describe this specialization.
1854 const TemplateArgumentList *TemplateArgs;
1855
1856 /// The point where this template was instantiated (if any)
1857 SourceLocation PointOfInstantiation;
1858
1859 /// The kind of specialization this declaration refers to.
1860 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1861 unsigned SpecializationKind : 3;
1862
1863 /// Indicate that we have matched a parameter pack with a non pack
1864 /// argument, when the opposite match is also allowed.
1865 /// This needs to be cached as deduction is performed during declaration,
1866 /// and we need the information to be preserved so that it is consistent
1867 /// during instantiation.
1868 LLVM_PREFERRED_TYPE(bool)
1869 unsigned StrictPackMatch : 1;
1870
1871protected:
1873 DeclContext *DC, SourceLocation StartLoc,
1874 SourceLocation IdLoc,
1875 ClassTemplateDecl *SpecializedTemplate,
1877 bool StrictPackMatch,
1879
1881
1882public:
1883 friend class ASTDeclReader;
1884 friend class ASTDeclWriter;
1885
1887 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1888 SourceLocation StartLoc, SourceLocation IdLoc,
1889 ClassTemplateDecl *SpecializedTemplate,
1890 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1893 GlobalDeclID ID);
1894
1895 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1896 bool Qualified) const override;
1897
1902
1907
1908 /// Retrieve the template that this specialization specializes.
1910
1911 /// Retrieve the template arguments of the class template
1912 /// specialization.
1914 return *TemplateArgs;
1915 }
1916
1918 TemplateArgs = Args;
1919 }
1920
1921 /// Determine the kind of specialization that this
1922 /// declaration represents.
1924 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1925 }
1926
1930
1931 /// Is this an explicit specialization at class scope (within the class that
1932 /// owns the primary template)? For example:
1933 ///
1934 /// \code
1935 /// template<typename T> struct Outer {
1936 /// template<typename U> struct Inner;
1937 /// template<> struct Inner; // class-scope explicit specialization
1938 /// };
1939 /// \endcode
1944
1945 /// True if this declaration is an explicit specialization,
1946 /// explicit instantiation declaration, or explicit instantiation
1947 /// definition.
1952
1954 SpecializedTemplate = Specialized;
1955 }
1956
1958 SpecializationKind = TSK;
1959 }
1960
1961 bool hasStrictPackMatch() const { return StrictPackMatch; }
1962
1963 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1964
1965 /// Get the point of instantiation (if any), or null if none.
1967 return PointOfInstantiation;
1968 }
1969
1971 assert(Loc.isValid() && "point of instantiation must be valid!");
1972 PointOfInstantiation = Loc;
1973 }
1974
1975 /// If this class template specialization is an instantiation of
1976 /// a template (rather than an explicit specialization), return the
1977 /// class template or class template partial specialization from which it
1978 /// was instantiated.
1979 llvm::PointerUnion<ClassTemplateDecl *,
1983 return llvm::PointerUnion<ClassTemplateDecl *,
1985
1987 }
1988
1989 /// Retrieve the class template or class template partial
1990 /// specialization which was specialized by this.
1991 llvm::PointerUnion<ClassTemplateDecl *,
1994 if (const auto *PartialSpec =
1995 dyn_cast<SpecializedPartialSpecialization *>(SpecializedTemplate))
1996 return PartialSpec->PartialSpecialization;
1997
1998 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1999 }
2000
2001 /// Retrieve the set of template arguments that should be used
2002 /// to instantiate members of the class template or class template partial
2003 /// specialization from which this class template specialization was
2004 /// instantiated.
2005 ///
2006 /// \returns For a class template specialization instantiated from the primary
2007 /// template, this function will return the same template arguments as
2008 /// getTemplateArgs(). For a class template specialization instantiated from
2009 /// a class template partial specialization, this function will return the
2010 /// deduced template arguments for the class template partial specialization
2011 /// itself.
2013 if (const auto *PartialSpec =
2014 dyn_cast<SpecializedPartialSpecialization *>(SpecializedTemplate))
2015 return *PartialSpec->TemplateArgs;
2016
2017 return getTemplateArgs();
2018 }
2019
2020 /// Note that this class template specialization is actually an
2021 /// instantiation of the given class template partial specialization whose
2022 /// template arguments have been deduced.
2024 const TemplateArgumentList *TemplateArgs) {
2025 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2026 "Already set to a class template partial specialization!");
2027 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2028 PS->PartialSpecialization = PartialSpec;
2029 PS->TemplateArgs = TemplateArgs;
2030 SpecializedTemplate = PS;
2031 }
2032
2033 /// Note that this class template specialization is an instantiation
2034 /// of the given class template.
2036 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2037 "Previously set to a class template partial specialization!");
2038 SpecializedTemplate = TemplDecl;
2039 }
2040
2041 /// Retrieve the template argument list as written in the sources,
2042 /// if any.
2044 if (auto *Info =
2045 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2046 return Info->TemplateArgsAsWritten;
2047 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2048 }
2049
2050 /// Set the template argument list as written in the sources.
2051 void
2053 if (auto *Info =
2054 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2055 Info->TemplateArgsAsWritten = ArgsWritten;
2056 else
2057 ExplicitInfo = ArgsWritten;
2058 }
2059
2060 /// Set the template argument list as written in the sources.
2065
2066 /// Gets the location of the extern keyword, if present.
2068 if (auto *Info =
2069 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2070 return Info->ExternKeywordLoc;
2071 return SourceLocation();
2072 }
2073
2074 /// Sets the location of the extern keyword.
2076
2077 /// Gets the location of the template keyword, if present.
2079 if (auto *Info =
2080 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2081 return Info->TemplateKeywordLoc;
2082 return SourceLocation();
2083 }
2084
2085 /// Sets the location of the template keyword.
2087
2088 SourceRange getSourceRange() const override LLVM_READONLY;
2089
2090 void Profile(llvm::FoldingSetNodeID &ID) const {
2091 Profile(ID, TemplateArgs->asArray(), getASTContext());
2092 }
2093
2094 static void
2095 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2096 const ASTContext &Context) {
2097 ID.AddInteger(TemplateArgs.size());
2098 for (const TemplateArgument &TemplateArg : TemplateArgs)
2099 TemplateArg.Profile(ID, Context);
2100 }
2101
2102 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2103
2104 static bool classofKind(Kind K) {
2105 return K >= firstClassTemplateSpecialization &&
2106 K <= lastClassTemplateSpecialization;
2107 }
2108};
2109
2110class ClassTemplatePartialSpecializationDecl
2112 /// The list of template parameters
2113 TemplateParameterList *TemplateParams = nullptr;
2114
2115 /// The class template partial specialization from which this
2116 /// class template partial specialization was instantiated.
2117 ///
2118 /// The boolean value will be true to indicate that this class template
2119 /// partial specialization was specialized at this level.
2120 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2121 InstantiatedFromMember;
2122
2123 mutable CanQualType CanonInjectedTST;
2124
2125 ClassTemplatePartialSpecializationDecl(
2126 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2128 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2129 CanQualType CanonInjectedTST,
2130 ClassTemplatePartialSpecializationDecl *PrevDecl);
2131
2132 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2133 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2134 InstantiatedFromMember(nullptr, false) {}
2135
2136 void anchor() override;
2137
2138public:
2139 friend class ASTDeclReader;
2140 friend class ASTDeclWriter;
2141
2142 static ClassTemplatePartialSpecializationDecl *
2143 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2144 SourceLocation StartLoc, SourceLocation IdLoc,
2145 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2146 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2147 ClassTemplatePartialSpecializationDecl *PrevDecl);
2148
2149 static ClassTemplatePartialSpecializationDecl *
2151
2152 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2154 static_cast<ClassTemplateSpecializationDecl *>(
2155 this)->getMostRecentDecl());
2156 }
2157
2158 /// Get the list of template parameters
2160 return TemplateParams;
2161 }
2162
2163 /// \brief All associated constraints of this partial specialization,
2164 /// including the requires clause and any constraints derived from
2165 /// constrained-parameters.
2166 ///
2167 /// The constraints in the resulting list are to be treated as if in a
2168 /// conjunction ("and").
2171 TemplateParams->getAssociatedConstraints(AC);
2172 }
2173
2175 return TemplateParams->hasAssociatedConstraints();
2176 }
2177
2178 /// Retrieve the member class template partial specialization from
2179 /// which this particular class template partial specialization was
2180 /// instantiated.
2181 ///
2182 /// \code
2183 /// template<typename T>
2184 /// struct Outer {
2185 /// template<typename U> struct Inner;
2186 /// template<typename U> struct Inner<U*> { }; // #1
2187 /// };
2188 ///
2189 /// Outer<float>::Inner<int*> ii;
2190 /// \endcode
2191 ///
2192 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2193 /// end up instantiating the partial specialization
2194 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2195 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2196 /// \c Outer<float>::Inner<U*>, this function would return
2197 /// \c Outer<T>::Inner<U*>.
2198 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2199 const auto *First =
2201 return First->InstantiatedFromMember.getPointer();
2202 }
2207
2209 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2211 First->InstantiatedFromMember.setPointer(PartialSpec);
2212 }
2213
2214 /// Determines whether this class template partial specialization
2215 /// template was a specialization of a member partial specialization.
2216 ///
2217 /// In the following example, the member template partial specialization
2218 /// \c X<int>::Inner<T*> is a member specialization.
2219 ///
2220 /// \code
2221 /// template<typename T>
2222 /// struct X {
2223 /// template<typename U> struct Inner;
2224 /// template<typename U> struct Inner<U*>;
2225 /// };
2226 ///
2227 /// template<> template<typename T>
2228 /// struct X<int>::Inner<T*> { /* ... */ };
2229 /// \endcode
2231 const auto *First =
2233 return First->InstantiatedFromMember.getInt();
2234 }
2235
2236 /// Note that this member template is a specialization.
2237 /// A partial specialization may be a member specialization even if it is not
2238 /// an instantiation of a member partial specialization.
2241 return First->InstantiatedFromMember.setInt(true);
2242 }
2243
2244 /// Retrieves the canonical injected specialization type for this partial
2245 /// specialization.
2248
2249 SourceRange getSourceRange() const override LLVM_READONLY;
2250
2251 void Profile(llvm::FoldingSetNodeID &ID) const {
2253 getASTContext());
2254 }
2255
2256 static void
2257 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2258 TemplateParameterList *TPL, const ASTContext &Context);
2259
2260 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2261
2262 static bool classofKind(Kind K) {
2263 return K == ClassTemplatePartialSpecialization;
2264 }
2265};
2266
2267/// Declaration of a class template.
2269protected:
2270 /// Data that is common to all of the declarations of a given
2271 /// class template.
2273 /// The class template specializations for this class
2274 /// template, including explicit specializations and instantiations.
2275 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2276
2277 /// The class template partial specializations for this class
2278 /// template.
2279 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2281
2282 /// The Injected Template Specialization Type for this declaration.
2284
2285 Common() = default;
2286 };
2287
2288 /// Retrieve the set of specializations of this class template.
2289 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2290 getSpecializations() const;
2291
2292 /// Retrieve the set of partial specializations of this class
2293 /// template.
2294 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2296
2299 NamedDecl *Decl)
2300 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2301
2302 CommonBase *newCommon(ASTContext &C) const override;
2303
2305 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2306 }
2307
2309
2310public:
2311
2312 friend class ASTDeclReader;
2313 friend class ASTDeclWriter;
2315
2316 /// Load any lazily-loaded specializations from the external source.
2317 void LoadLazySpecializations(bool OnlyPartial = false) const;
2318
2319 /// Get the underlying class declarations of the template.
2321 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2322 }
2323
2324 /// Returns whether this template declaration defines the primary
2325 /// class pattern.
2329
2330 /// \brief Create a class template node.
2333 DeclarationName Name,
2334 TemplateParameterList *Params,
2335 NamedDecl *Decl);
2336
2337 /// Create an empty class template node.
2339
2340 /// Return the specialization with the provided arguments if it exists,
2341 /// otherwise return the insertion point.
2344 llvm::FoldingSetInsertToken &InsertToken);
2345
2346 /// Insert the specified specialization knowing that it is not already
2347 /// in. InsertToken must be obtained from findSpecialization.
2349 llvm::FoldingSetInsertToken InsertToken);
2350
2359
2360 /// Retrieve the previous declaration of this class template, or
2361 /// nullptr if no such declaration exists.
2363 return cast_or_null<ClassTemplateDecl>(
2364 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2365 }
2367 return cast_or_null<ClassTemplateDecl>(
2368 static_cast<const RedeclarableTemplateDecl *>(
2369 this)->getPreviousDecl());
2370 }
2371
2377 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2378 }
2379
2381 return cast_or_null<ClassTemplateDecl>(
2383 }
2384
2385 /// Return the partial specialization with the provided arguments if it
2386 /// exists, otherwise return the insertion point.
2390 llvm::FoldingSetInsertToken &InsertToken);
2391
2392 /// Insert the specified partial specialization knowing that it is not
2393 /// already in. InsertToken must be obtained from findPartialSpecialization.
2395 llvm::FoldingSetInsertToken InsertToken);
2396
2397 /// Retrieve the partial specializations as an ordered list.
2400
2401 /// Find a class template partial specialization with the given
2402 /// type T.
2403 ///
2404 /// \param T a dependent type that names a specialization of this class
2405 /// template.
2406 ///
2407 /// \returns the class template partial specialization that exactly matches
2408 /// the type \p T, or nullptr if no such partial specialization exists.
2410
2411 /// Find a class template partial specialization which was instantiated
2412 /// from the given member partial specialization.
2413 ///
2414 /// \param D a member class template partial specialization.
2415 ///
2416 /// \returns the class template partial specialization which was instantiated
2417 /// from the given member partial specialization, or nullptr if no such
2418 /// partial specialization exists.
2422
2423 /// Retrieve the canonical template specialization type of the
2424 /// injected-class-name for this class template.
2425 ///
2426 /// The injected-class-name for a class template \c X is \c
2427 /// X<template-args>, where \c template-args is formed from the
2428 /// template arguments that correspond to the template parameters of
2429 /// \c X. For example:
2430 ///
2431 /// \code
2432 /// template<typename T, int N>
2433 /// struct array {
2434 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2435 /// };
2436 /// \endcode
2439
2441 using spec_range = llvm::iterator_range<spec_iterator>;
2442
2444 return spec_range(spec_begin(), spec_end());
2445 }
2446
2448 return makeSpecIterator(getSpecializations(), false);
2449 }
2450
2452 return makeSpecIterator(getSpecializations(), true);
2453 }
2454
2455 // Implement isa/cast/dyncast support
2456 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2457 static bool classofKind(Kind K) { return K == ClassTemplate; }
2458};
2459
2460/// Declaration of a friend template.
2461///
2462/// For example:
2463/// \code
2464/// template <typename T> class A {
2465/// friend class MyVector<T>; // not a friend template
2466/// template <typename U> friend class B; // friend class template
2467/// template <typename U> friend class Foo<T>::Nested; // friend template
2468/// };
2469/// \endcode
2470class FriendTemplateDecl final
2471 : public FriendDecl,
2472 private llvm::TrailingObjects<FriendTemplateDecl,
2473 TemplateParameterList *> {
2474 void anchor() override;
2475
2476private:
2477 unsigned NumTPLists = 0;
2478 TemplateName Template;
2479
2480 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, FriendUnion Friend,
2481 SourceLocation FriendLoc, SourceLocation EllipsisLoc,
2483 TemplateName Template = {})
2484 : FriendDecl(Decl::FriendTemplate, DC, Loc, Friend, FriendLoc,
2485 EllipsisLoc),
2486 NumTPLists(FriendTPLists.size()), Template(Template) {
2487 assert(!FriendTPLists.empty());
2488 llvm::copy(FriendTPLists, getTrailingObjects());
2489 }
2490
2491 FriendTemplateDecl(EmptyShell Empty, unsigned NumFriendTPLists)
2492 : FriendDecl(Decl::FriendTemplate, Empty), NumTPLists(NumFriendTPLists) {
2493 assert(NumFriendTPLists != 0);
2494 }
2495
2496public:
2497 friend class ASTDeclReader;
2498 friend class ASTDeclWriter;
2500
2501 enum class FriendTemplateEntityKind { Type, Template, Decl };
2502
2503 static FriendTemplateDecl *
2504 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2507 SourceLocation EllipsisLoc = {}, TemplateName Template = {});
2508
2509 static FriendTemplateDecl *
2510 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2511 TemplateName Template, SourceLocation FriendLoc,
2512 ArrayRef<TemplateParameterList *> FriendTPLists,
2513 SourceLocation EllipsisLoc = {});
2514
2515 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
2516 unsigned NumFriendTPLists);
2517
2518 SourceRange getSourceRange() const override LLVM_READONLY;
2519
2520 TemplateName getFriendTemplateName() const { return Template; }
2521
2523 if (getFriendType())
2525 if (Template.isNull())
2528 }
2529
2530 NamedDecl *getFriendDecl() const override {
2531 if (NamedDecl *ND = dyn_cast_if_present<NamedDecl *>(Friend))
2532 return ND;
2533 return Template.getAsTemplateDecl();
2534 }
2535
2537 return ArrayRef(getTrailingObjects(), NumTPLists);
2538 }
2539
2540 // Implement isa/cast/dyncast/etc.
2541 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2542 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2543};
2544
2545/// Declaration of an alias template.
2546///
2547/// For example:
2548/// \code
2549/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2550/// \endcode
2552protected:
2554
2560
2561 CommonBase *newCommon(ASTContext &C) const override;
2562
2564 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2565 }
2566
2567public:
2568 friend class ASTDeclReader;
2569 friend class ASTDeclWriter;
2570
2571 /// Get the underlying function declaration of the template.
2573 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2574 }
2575
2576
2585
2586 /// Retrieve the previous declaration of this function template, or
2587 /// nullptr if no such declaration exists.
2589 return cast_or_null<TypeAliasTemplateDecl>(
2590 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2591 }
2593 return cast_or_null<TypeAliasTemplateDecl>(
2594 static_cast<const RedeclarableTemplateDecl *>(
2595 this)->getPreviousDecl());
2596 }
2597
2599 return cast_or_null<TypeAliasTemplateDecl>(
2601 }
2602
2603 /// Create a function template node.
2606 DeclarationName Name,
2607 TemplateParameterList *Params,
2608 NamedDecl *Decl);
2609
2610 /// Create an empty alias template node.
2612 GlobalDeclID ID);
2613
2614 // Implement isa/cast/dyncast support
2615 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2616 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2617};
2618
2619/// Represents a variable template specialization, which refers to
2620/// a variable template with a given set of template arguments.
2621///
2622/// Variable template specializations represent both explicit
2623/// specializations of variable templates, as in the example below, and
2624/// implicit instantiations of variable templates.
2625///
2626/// \code
2627/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2628///
2629/// template<>
2630/// constexpr float pi<float>; // variable template specialization pi<float>
2631/// \endcode
2633 public llvm::FoldingSetNode {
2634
2635 /// Structure that stores information about a variable template
2636 /// specialization that was instantiated from a variable template partial
2637 /// specialization.
2638 struct SpecializedPartialSpecialization {
2639 /// The variable template partial specialization from which this
2640 /// variable template specialization was instantiated.
2641 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2642
2643 /// The template argument list deduced for the variable template
2644 /// partial specialization itself.
2645 const TemplateArgumentList *TemplateArgs;
2646 };
2647
2648 /// The template that this specialization specializes.
2649 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2650 SpecializedTemplate;
2651
2652 /// Further info for explicit template specialization/instantiation.
2653 /// Does not apply to implicit specializations.
2654 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2655
2656 /// The template arguments used to describe this specialization.
2657 const TemplateArgumentList *TemplateArgs;
2658
2659 /// The point where this template was instantiated (if any).
2660 SourceLocation PointOfInstantiation;
2661
2662 /// The kind of specialization this declaration refers to.
2663 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2664 unsigned SpecializationKind : 3;
2665
2666 /// Whether this declaration is a complete definition of the
2667 /// variable template specialization. We can't otherwise tell apart
2668 /// an instantiated declaration from an instantiated definition with
2669 /// no initializer.
2670 LLVM_PREFERRED_TYPE(bool)
2671 unsigned IsCompleteDefinition : 1;
2672
2673protected:
2675 SourceLocation StartLoc, SourceLocation IdLoc,
2676 VarTemplateDecl *SpecializedTemplate,
2677 QualType T, TypeSourceInfo *TInfo,
2678 StorageClass S,
2680
2681 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2682
2683public:
2684 friend class ASTDeclReader;
2685 friend class ASTDeclWriter;
2686 friend class VarDecl;
2687
2689 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2690 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2691 TypeSourceInfo *TInfo, StorageClass S,
2694 GlobalDeclID ID);
2695
2696 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2697 bool Qualified) const override;
2698
2700 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2702 }
2703
2704 /// Retrieve the template that this specialization specializes.
2706
2707 /// Retrieve the template arguments of the variable template
2708 /// specialization.
2709 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2710
2711 /// Determine the kind of specialization that this
2712 /// declaration represents.
2714 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2715 }
2716
2720
2725
2726 /// True if this declaration is an explicit specialization,
2727 /// explicit instantiation declaration, or explicit instantiation
2728 /// definition.
2733
2735 SpecializationKind = TSK;
2736 }
2737
2738 /// Get the point of instantiation (if any), or null if none.
2740 return PointOfInstantiation;
2741 }
2742
2744 assert(Loc.isValid() && "point of instantiation must be valid!");
2745 PointOfInstantiation = Loc;
2746 }
2747
2748 void setCompleteDefinition() { IsCompleteDefinition = true; }
2749
2750 /// If this variable template specialization is an instantiation of
2751 /// a template (rather than an explicit specialization), return the
2752 /// variable template or variable template partial specialization from which
2753 /// it was instantiated.
2754 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2757 return llvm::PointerUnion<VarTemplateDecl *,
2759
2761 }
2762
2763 /// Retrieve the variable template or variable template partial
2764 /// specialization which was specialized by this.
2765 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2767 if (const auto *PartialSpec =
2768 dyn_cast<SpecializedPartialSpecialization *>(SpecializedTemplate))
2769 return PartialSpec->PartialSpecialization;
2770
2771 return cast<VarTemplateDecl *>(SpecializedTemplate);
2772 }
2773
2774 /// Retrieve the set of template arguments that should be used
2775 /// to instantiate the initializer of the variable template or variable
2776 /// template partial specialization from which this variable template
2777 /// specialization was instantiated.
2778 ///
2779 /// \returns For a variable template specialization instantiated from the
2780 /// primary template, this function will return the same template arguments
2781 /// as getTemplateArgs(). For a variable template specialization instantiated
2782 /// from a variable template partial specialization, this function will the
2783 /// return deduced template arguments for the variable template partial
2784 /// specialization itself.
2786 if (const auto *PartialSpec =
2787 dyn_cast<SpecializedPartialSpecialization *>(SpecializedTemplate))
2788 return *PartialSpec->TemplateArgs;
2789
2790 return getTemplateArgs();
2791 }
2792
2793 /// Note that this variable template specialization is actually an
2794 /// instantiation of the given variable template partial specialization whose
2795 /// template arguments have been deduced.
2797 const TemplateArgumentList *TemplateArgs) {
2798 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2799 "Already set to a variable template partial specialization!");
2800 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2801 PS->PartialSpecialization = PartialSpec;
2802 PS->TemplateArgs = TemplateArgs;
2803 SpecializedTemplate = PS;
2804 }
2805
2806 /// Note that this variable template specialization is an instantiation
2807 /// of the given variable template.
2809 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2810 "Previously set to a variable template partial specialization!");
2811 SpecializedTemplate = TemplDecl;
2812 }
2813
2814 /// Retrieve the template argument list as written in the sources,
2815 /// if any.
2817 if (auto *Info =
2818 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2819 return Info->TemplateArgsAsWritten;
2820 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2821 }
2822
2823 /// Set the template argument list as written in the sources.
2824 void
2826 if (auto *Info =
2827 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2828 Info->TemplateArgsAsWritten = ArgsWritten;
2829 else
2830 ExplicitInfo = ArgsWritten;
2831 }
2832
2833 /// Set the template argument list as written in the sources.
2838
2839 /// Gets the location of the extern keyword, if present.
2841 if (auto *Info =
2842 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2843 return Info->ExternKeywordLoc;
2844 return SourceLocation();
2845 }
2846
2847 /// Sets the location of the extern keyword.
2849
2850 /// Gets the location of the template keyword, if present.
2852 if (auto *Info =
2853 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2854 return Info->TemplateKeywordLoc;
2855 return SourceLocation();
2856 }
2857
2858 /// Sets the location of the template keyword.
2860
2861 SourceRange getSourceRange() const override LLVM_READONLY;
2862
2863 void Profile(llvm::FoldingSetNodeID &ID) const {
2864 Profile(ID, TemplateArgs->asArray(), getASTContext());
2865 }
2866
2867 static void Profile(llvm::FoldingSetNodeID &ID,
2868 ArrayRef<TemplateArgument> TemplateArgs,
2869 const ASTContext &Context) {
2870 ID.AddInteger(TemplateArgs.size());
2871 for (const TemplateArgument &TemplateArg : TemplateArgs)
2872 TemplateArg.Profile(ID, Context);
2873 }
2874
2875 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2876
2877 static bool classofKind(Kind K) {
2878 return K >= firstVarTemplateSpecialization &&
2879 K <= lastVarTemplateSpecialization;
2880 }
2881};
2882
2883class VarTemplatePartialSpecializationDecl
2885 /// The list of template parameters
2886 TemplateParameterList *TemplateParams = nullptr;
2887
2888 /// The variable template partial specialization from which this
2889 /// variable template partial specialization was instantiated.
2890 ///
2891 /// The boolean value will be true to indicate that this variable template
2892 /// partial specialization was specialized at this level.
2893 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2894 InstantiatedFromMember;
2895
2896 VarTemplatePartialSpecializationDecl(
2897 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2899 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2901
2902 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2903 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2904 Context),
2905 InstantiatedFromMember(nullptr, false) {}
2906
2907 void anchor() override;
2908
2909public:
2910 friend class ASTDeclReader;
2911 friend class ASTDeclWriter;
2912
2913 static VarTemplatePartialSpecializationDecl *
2914 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2916 VarTemplateDecl *SpecializedTemplate, QualType T,
2917 TypeSourceInfo *TInfo, StorageClass S,
2919
2920 static VarTemplatePartialSpecializationDecl *
2922
2923 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2925 static_cast<VarTemplateSpecializationDecl *>(
2926 this)->getMostRecentDecl());
2927 }
2928
2929 /// Get the list of template parameters
2931 return TemplateParams;
2932 }
2933
2934 /// Get the template argument list of the template parameter list.
2936 getInjectedTemplateArgs(const ASTContext &Context) const {
2938 }
2939
2940 /// \brief All associated constraints of this partial specialization,
2941 /// including the requires clause and any constraints derived from
2942 /// constrained-parameters.
2943 ///
2944 /// The constraints in the resulting list are to be treated as if in a
2945 /// conjunction ("and").
2948 TemplateParams->getAssociatedConstraints(AC);
2949 }
2950
2952 return TemplateParams->hasAssociatedConstraints();
2953 }
2954
2955 /// \brief Retrieve the member variable template partial specialization from
2956 /// which this particular variable template partial specialization was
2957 /// instantiated.
2958 ///
2959 /// \code
2960 /// template<typename T>
2961 /// struct Outer {
2962 /// template<typename U> U Inner;
2963 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2964 /// };
2965 ///
2966 /// template int* Outer<float>::Inner<int*>;
2967 /// \endcode
2968 ///
2969 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2970 /// end up instantiating the partial specialization
2971 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2972 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2973 /// \c Outer<float>::Inner<U*>, this function would return
2974 /// \c Outer<T>::Inner<U*>.
2975 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2976 const auto *First =
2978 return First->InstantiatedFromMember.getPointer();
2979 }
2980
2981 void
2982 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2984 First->InstantiatedFromMember.setPointer(PartialSpec);
2985 }
2986
2987 /// Determines whether this variable template partial specialization
2988 /// was a specialization of a member partial specialization.
2989 ///
2990 /// In the following example, the member template partial specialization
2991 /// \c X<int>::Inner<T*> is a member specialization.
2992 ///
2993 /// \code
2994 /// template<typename T>
2995 /// struct X {
2996 /// template<typename U> U Inner;
2997 /// template<typename U> U* Inner<U*> = (U*)(0);
2998 /// };
2999 ///
3000 /// template<> template<typename T>
3001 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
3002 /// \endcode
3004 const auto *First =
3006 return First->InstantiatedFromMember.getInt();
3007 }
3008
3009 /// Note that this member template is a specialization.
3010 /// A partial specialization may be a member specialization even if it is not
3011 /// an instantiation of a member partial specialization.
3014 return First->InstantiatedFromMember.setInt(true);
3015 }
3016
3017 SourceRange getSourceRange() const override LLVM_READONLY;
3018
3019 void Profile(llvm::FoldingSetNodeID &ID) const {
3021 getASTContext());
3022 }
3023
3024 static void
3025 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3026 TemplateParameterList *TPL, const ASTContext &Context);
3027
3028 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3029
3030 static bool classofKind(Kind K) {
3031 return K == VarTemplatePartialSpecialization;
3032 }
3033};
3034
3035/// Declaration of a variable template.
3037protected:
3038 /// Data that is common to all of the declarations of a given
3039 /// variable template.
3041 /// The variable template specializations for this variable
3042 /// template, including explicit specializations and instantiations.
3043 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3044
3045 /// The variable template partial specializations for this variable
3046 /// template.
3047 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3049
3050 Common() = default;
3051 };
3052
3053 /// Retrieve the set of specializations of this variable template.
3054 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3055 getSpecializations() const;
3056
3057 /// Retrieve the set of partial specializations of this class
3058 /// template.
3059 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3061
3066
3067 CommonBase *newCommon(ASTContext &C) const override;
3068
3070 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3071 }
3072
3073public:
3074 friend class ASTDeclReader;
3075 friend class ASTDeclWriter;
3076
3077 /// Load any lazily-loaded specializations from the external source.
3078 void LoadLazySpecializations(bool OnlyPartial = false) const;
3079
3080 /// Get the underlying variable declarations of the template.
3082 return static_cast<VarDecl *>(TemplatedDecl);
3083 }
3084
3085 /// Returns whether this template declaration defines the primary
3086 /// variable pattern.
3090
3092
3093 /// Create a variable template node.
3096 TemplateParameterList *Params,
3097 VarDecl *Decl);
3098
3099 /// Create an empty variable template node.
3101
3102 /// Return the specialization with the provided arguments if it exists,
3103 /// otherwise return the insertion point.
3106 llvm::FoldingSetInsertToken &InsertToken);
3107
3108 /// Insert the specified specialization knowing that it is not already
3109 /// in. InsertToken must be obtained from findSpecialization.
3111 llvm::FoldingSetInsertToken InsertToken);
3112
3119
3120 /// Retrieve the previous declaration of this variable template, or
3121 /// nullptr if no such declaration exists.
3123 return cast_or_null<VarTemplateDecl>(
3124 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3125 }
3127 return cast_or_null<VarTemplateDecl>(
3128 static_cast<const RedeclarableTemplateDecl *>(
3129 this)->getPreviousDecl());
3130 }
3131
3137 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3138 }
3139
3144
3145 /// Return the partial specialization with the provided arguments if it
3146 /// exists, otherwise return the insertion point.
3150 llvm::FoldingSetInsertToken &InsertToken);
3151
3152 /// Insert the specified partial specialization knowing that it is not
3153 /// already in. InsertToken must be obtained from findPartialSpecialization.
3155 llvm::FoldingSetInsertToken InsertToken);
3156
3157 /// Retrieve the partial specializations as an ordered list.
3160
3161 /// Find a variable template partial specialization which was
3162 /// instantiated
3163 /// from the given member partial specialization.
3164 ///
3165 /// \param D a member variable template partial specialization.
3166 ///
3167 /// \returns the variable template partial specialization which was
3168 /// instantiated
3169 /// from the given member partial specialization, or nullptr if no such
3170 /// partial specialization exists.
3173
3175 using spec_range = llvm::iterator_range<spec_iterator>;
3176
3178 return spec_range(spec_begin(), spec_end());
3179 }
3180
3182 return makeSpecIterator(getSpecializations(), false);
3183 }
3184
3186 return makeSpecIterator(getSpecializations(), true);
3187 }
3188
3189 // Implement isa/cast/dyncast support
3190 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3191 static bool classofKind(Kind K) { return K == VarTemplate; }
3192};
3193
3194/// Declaration of a C++20 concept.
3195class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3196protected:
3198
3203public:
3205 DeclarationName Name,
3206 TemplateParameterList *Params,
3207 Expr *ConstraintExpr = nullptr);
3209
3211 return ConstraintExpr;
3212 }
3213
3214 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3215
3217
3218 SourceRange getSourceRange() const override LLVM_READONLY {
3219 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3220 ConstraintExpr ? ConstraintExpr->getEndLoc()
3221 : SourceLocation());
3222 }
3223
3224 bool isTypeConcept() const {
3225 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3226 }
3227
3230 }
3232 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3233 }
3234
3235 // Implement isa/cast/dyncast/etc.
3236 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3237 static bool classofKind(Kind K) { return K == Concept; }
3238
3239 friend class ASTReader;
3240 friend class ASTDeclReader;
3241 friend class ASTDeclWriter;
3242};
3243
3244// An implementation detail of ConceptSpecialicationExpr that holds the template
3245// arguments, so we can later use this to reconstitute the template arguments
3246// during constraint checking.
3247class ImplicitConceptSpecializationDecl final
3248 : public Decl,
3249 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3250 TemplateArgument> {
3251 unsigned NumTemplateArgs;
3252
3253 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3254 ArrayRef<TemplateArgument> ConvertedArgs);
3255 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3256
3257public:
3258 static ImplicitConceptSpecializationDecl *
3260 ArrayRef<TemplateArgument> ConvertedArgs);
3261 static ImplicitConceptSpecializationDecl *
3263 unsigned NumTemplateArgs);
3264
3266 return getTrailingObjects(NumTemplateArgs);
3267 }
3269
3270 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3271 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3272
3274 friend class ASTDeclReader;
3275};
3276
3277/// A template parameter object.
3278///
3279/// Template parameter objects represent values of class type used as template
3280/// arguments. There is one template parameter object for each such distinct
3281/// value used as a template argument across the program.
3282///
3283/// \code
3284/// struct A { int x, y; };
3285/// template<A> struct S;
3286/// S<A{1, 2}> s1;
3287/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3288/// \endcode
3289class TemplateParamObjectDecl : public ValueDecl,
3290 public Mergeable<TemplateParamObjectDecl>,
3291 public llvm::FoldingSetNode {
3292private:
3293 /// The value of this template parameter object.
3294 APValue Value;
3295
3296 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3297 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3298 T),
3299 Value(V) {}
3300
3301 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3302 const APValue &V);
3303 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3304 GlobalDeclID ID);
3305
3306 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3307 /// create these.
3308 friend class ASTContext;
3309 friend class ASTReader;
3310 friend class ASTDeclReader;
3311
3312public:
3313 /// Print this template parameter object in a human-readable format.
3314 void printName(llvm::raw_ostream &OS,
3315 const PrintingPolicy &Policy) const override;
3316
3317 /// Print this object as an equivalent expression.
3318 void printAsExpr(llvm::raw_ostream &OS) const;
3319 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3320
3321 /// Print this object as an initializer suitable for a variable of the
3322 /// object's type.
3323 void printAsInit(llvm::raw_ostream &OS) const;
3324 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3325
3326 const APValue &getValue() const { return Value; }
3327
3328 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3329 const APValue &V) {
3330 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3331 V.Profile(ID);
3332 }
3333 void Profile(llvm::FoldingSetNodeID &ID) {
3334 Profile(ID, getType(), getValue());
3335 }
3336
3337 TemplateParamObjectDecl *getCanonicalDecl() override {
3338 return getFirstDecl();
3339 }
3340 const TemplateParamObjectDecl *getCanonicalDecl() const {
3341 return getFirstDecl();
3342 }
3343
3344 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3345 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3346};
3347
3348/// Represents a C++26 expansion statement declaration.
3349///
3350/// This is a bit of a hack, since expansion statements shouldn't really be
3351/// 'declarations' per se (they don't declare anything). Nevertheless, we *do*
3352/// need them to be declaration *contexts*, because the DeclContext is used to
3353/// compute the 'template depth' of entities enclosed therein. In particular,
3354/// the 'template depth' is used to find instantiations of parameter variables.
3355/// A lambda enclosed within an expansion statement cannot compute its
3356/// template depth without a pointer to the enclosing expansion statement.
3357///
3358/// For the remainder of this comment, let 'expanding' an expansion statement
3359/// refer to the process of performing template substitution on its body N
3360/// times, where N is the expansion size (how this size is determined depends on
3361/// the kind of expansion statement); by contrast we may sometimes 'instantiate'
3362/// an expansion statement (because it happens to be in a template). This is
3363/// just regular template instantiation.
3364///
3365/// This node contains a 'CXXExpansionStmtPattern' as well as a
3366/// 'CXXExpansionStmtInstantiation'. These two members correspond to
3367/// distinct representations of the expansion statement: the former is used
3368/// prior to expansion and contains all the parts needed to perform expansion;
3369/// the latter holds the expanded/desugared AST nodes that result from the
3370/// expansion.
3371///
3372/// Additionally, there is a 'NonTypeTemplateParmDecl', which is a template
3373/// parameter that serves as the expansion index, e.g. during the N-th
3374/// expansion, it is set to 'N'. See the documentation of
3375/// 'CXXExpansionStmtPattern', for more information on how this is used.
3376///
3377/// After expansion, the 'CXXExpansionStmtPattern' is no longer updated and left
3378/// as-is; this also means that, if an already-expanded expansion statement is
3379/// inside a template, and that template is then instantiated, the
3380/// 'CXXExpansionStmtPattern' is *not* instantiated; only the
3381/// 'CXXExpansionStmtInstantiation' is. The latter is also what's used for
3382/// codegen and constant evaluation.
3383///
3384/// There are different kinds of expansion statements; see the comment on
3385/// 'CXXExpansionStmtPattern' for more information.
3386///
3387/// As an example, if the user writes the following expansion statement:
3388/// \verbatim
3389/// std::tuple<int, int, int> a{1, 2, 3};
3390/// template for (auto x : a) {
3391/// // ...
3392/// }
3393/// \endverbatim
3394///
3395/// The 'CXXExpansionStmtPattern' of this particular 'CXXExpansionStmtDecl'
3396/// stores, amongst other things, the declaration of the variable 'x' as well
3397/// as the expansion-initializer 'a'.
3398///
3399/// After expansion, we end up with a 'CXXExpansionStmtInstantiation' that
3400/// is *equivalent* to the AST shown below. Note that only the inner '{}' (i.e.
3401/// those marked as 'Actual "CompoundStmt"' below) are actually present as
3402/// 'CompoundStmt's in the AST; the outer braces that wrap everything do *not*
3403/// correspond to an actual 'CompoundStmt' and are implicit in the sense that we
3404/// simply push a scope when evaluating or emitting IR for a
3405/// 'CXXExpansionStmtInstantiation'.
3406///
3407/// \verbatim
3408/// { // Not actually present in the AST.
3409/// auto [__u0, __u1, __u2] = a;
3410/// { // Actual 'CompoundStmt'.
3411/// auto x = __u0;
3412/// // ...
3413/// }
3414/// { // Actual 'CompoundStmt'.
3415/// auto x = __u1;
3416/// // ...
3417/// }
3418/// { // Actual 'CompoundStmt'.
3419/// auto x = __u2;
3420/// // ...
3421/// }
3422/// }
3423/// \endverbatim
3424///
3425/// See the documentation around 'CXXExpansionStmtInstantiation' for more notes
3426/// as to why this node exist and how it is used.
3427///
3428/// \see CXXExpansionStmtPattern
3429/// \see CXXExpansionStmtInstantiation
3430class CXXExpansionStmtDecl : public Decl, public DeclContext {
3431 CXXExpansionStmtPattern *Pattern = nullptr;
3432 NonTypeTemplateParmDecl *IndexNTTP = nullptr;
3433 CXXExpansionStmtInstantiation *Instantiations = nullptr;
3434
3435 CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
3437
3438public:
3439 friend class ASTDeclReader;
3440
3441 static CXXExpansionStmtDecl *Create(ASTContext &C, DeclContext *DC,
3442 SourceLocation Loc,
3444 static CXXExpansionStmtDecl *CreateDeserialized(ASTContext &C,
3445 GlobalDeclID ID);
3446
3448 const CXXExpansionStmtPattern *getExpansionPattern() const { return Pattern; }
3450
3453 return Instantiations;
3454 }
3455
3457 Instantiations = S;
3458 }
3459
3462 return IndexNTTP;
3463 }
3464
3465 SourceRange getSourceRange() const override LLVM_READONLY;
3466
3467 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3468 static bool classofKind(Kind K) { return K == CXXExpansionStmt; }
3469};
3470
3472 if (auto *PD = dyn_cast<TemplateTypeParmDecl *>(P))
3473 return PD;
3474 if (auto *PD = dyn_cast<NonTypeTemplateParmDecl *>(P))
3475 return PD;
3477}
3478
3480 auto *TD = dyn_cast<TemplateDecl>(D);
3481 return TD && (isa<ClassTemplateDecl>(TD) ||
3484 [&]() {
3485 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
3486 return TTP->templateParameterKind() == TNK_Type_template;
3487 return false;
3488 }())
3489 ? TD
3490 : nullptr;
3491}
3492
3493/// Check whether the template parameter is a pack expansion, and if so,
3494/// determine the number of parameters produced by that expansion. For instance:
3495///
3496/// \code
3497/// template<typename ...Ts> struct A {
3498/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3499/// };
3500/// \endcode
3501///
3502/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3503/// is not a pack expansion, so returns an empty Optional.
3505 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3506 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3507 return Num;
3508 }
3509
3510 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3511 if (NTTP->isExpandedParameterPack())
3512 return NTTP->getNumExpansionTypes();
3513 }
3514
3515 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3516 if (TTP->isExpandedParameterPack())
3517 return TTP->getNumExpansionTemplateParameters();
3518 }
3519
3520 return std::nullopt;
3521}
3522
3523/// Internal helper used by Subst* nodes to retrieve a parameter from the
3524/// AssociatedDecl, and the template argument substituted into it, if any.
3525std::tuple<NamedDecl *, TemplateArgument>
3526getReplacedTemplateParameter(Decl *D, unsigned Index);
3527
3528/// If we have a 'templated' declaration for a template, adjust 'D' to
3529/// refer to the actual template.
3530/// If we have an implicit instantiation, adjust 'D' to refer to template.
3531const Decl &adjustDeclToTemplate(const Decl &D);
3532
3533/// Represents an explicit instantiation of a template entity in source code.
3534///
3535/// \code
3536/// template void ns::foo<int>(int); // function template
3537/// extern template struct ns::S<int>; // class template (extern)
3538/// template int ns::bar<int>; // variable template
3539/// template void ns::S<int>::method(int); // member function
3540/// \endcode
3541class ExplicitInstantiationDecl final
3542 : public Decl,
3543 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3544 NestedNameSpecifierLoc,
3545 const ASTTemplateArgumentListInfo *> {
3546 friend class ASTDeclReader;
3547 friend class ASTDeclWriter;
3548 friend TrailingObjects;
3549
3550 /// The underlying specialization (low 3 bits: TSK).
3551 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3552
3553 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3554 /// Always non-null after construction.
3555 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3556 /// qualifier, template-name, and argument locations.
3557 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3558 /// - Function / variable templates: the declared type.
3559 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3560
3561 /// Location of the 'extern' keyword (invalid if not extern template).
3562 SourceLocation ExternLoc;
3563
3564 /// Location of the entity name (e.g., 'foo' in 'template void
3565 /// ns::foo<int>(int)').
3566 SourceLocation NameLoc;
3567
3568 enum TrailingFlags : unsigned {
3569 HasQualifierFlag = 1,
3570 HasArgsAsWrittenFlag = 2,
3571 };
3572
3573 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3574 return hasTrailingQualifier() ? 1 : 0;
3575 }
3576
3577 /// For class templates / nested classes, returns the TypeLoc encoding the
3578 /// entity (TemplateSpecializationTypeLoc or TagTypeLoc). For function /
3579 /// variable templates -- where TypeSourceInfo holds the declared type
3580 /// rather than the entity -- returns std::nullopt.
3581 std::optional<TypeLoc> getClassTypeLoc() const {
3583 return std::nullopt;
3584 if (auto *TSI = TypeAndFlags.getPointer())
3585 return TSI->getTypeLoc();
3586 return std::nullopt;
3587 }
3588
3589 /// Raw TypeSourceInfo pointer, needed by the serializer.
3590 TypeSourceInfo *getRawTypeSourceInfo() const {
3591 return TypeAndFlags.getPointer();
3592 }
3593
3594 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3595 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3597 return nullptr;
3598 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3599 }
3600
3601 ExplicitInstantiationDecl(
3602 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3603 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3604 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3605 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3606
3607 ExplicitInstantiationDecl(EmptyShell Empty)
3609
3610public:
3611 static ExplicitInstantiationDecl *
3612 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3613 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3614 NestedNameSpecifierLoc QualifierLoc,
3615 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3616 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3618
3619 static ExplicitInstantiationDecl *
3620 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3621
3622 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3623
3624 SourceRange getSourceRange() const override LLVM_READONLY;
3625 SourceLocation getEndLoc() const LLVM_READONLY;
3626
3627 SourceLocation getExternLoc() const { return ExternLoc; }
3629 SourceLocation getNameLoc() const { return NameLoc; }
3630
3631 /// The tag keyword (struct/class/union) location for class templates /
3632 /// nested classes; invalid for function / variable templates.
3634
3636 return TypeAndFlags.getInt() & HasQualifierFlag;
3637 }
3639 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3640 }
3641
3642 /// Returns the qualifier regardless of where it is stored.
3643 /// For class templates / nested classes, extracted from the class TypeLoc;
3644 /// for function / variable templates, from a trailing object.
3646
3647 /// Returns the number of explicit template arguments, or std::nullopt if
3648 /// this entity has no template argument list (e.g., nested classes).
3649 std::optional<unsigned> getNumTemplateArgs() const;
3650 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3653
3654 /// The declared type (return type or variable type) for function / variable
3655 /// templates. Null for class templates and nested classes.
3657
3659 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3660 }
3661
3662 bool isExternTemplate() const { return ExternLoc.isValid(); }
3663
3664 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3665 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3666};
3667
3668} // namespace clang
3669
3670#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:504
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:245
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:158
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
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:540
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:556
friend class DeclContext
Definition DeclCXX.h:267
Declaration of a class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
ClassTemplateDecl * getMostRecentDecl()
spec_iterator spec_begin() const
spec_iterator spec_end() const
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
static bool classofKind(Kind K)
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
llvm::iterator_range< spec_iterator > spec_range
static bool classof(const Decl *D)
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
const ClassTemplateDecl * getMostRecentDecl() const
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
const ClassTemplateDecl * getCanonicalDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
SpecIterator< ClassTemplateSpecializationDecl > spec_iterator
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
void setCommonPtr(Common *C)
spec_range specializations() const
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
friend class TemplateDeclInstantiator
Common * getCommonPtr() const
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setMemberSpecialization()
Note that this member template is a specialization.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
static bool classof(const Decl *D)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
ClassTemplateSpecializationDecl * getDefinitionOrSelf() const
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
void setDefinition(Expr *E)
Expr * getConstraintExpr() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
friend class ASTReader
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
friend class ASTDeclReader
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasDefinition() const
static bool classof(const Decl *D)
friend class ASTDeclWriter
const ConceptDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1467
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:602
virtual Decl * getPreviousDeclImpl()
Implementation of getPreviousDecl(), to be overridden by any subclass that has a redeclaration chain.
Definition DeclBase.h:1013
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:1009
SourceLocation getLocation() const
Definition DeclBase.h:448
virtual Decl * getMostRecentDeclImpl()
Implementation of getMostRecentDecl(), to be overridden by any subclass that has a redeclaration chai...
Definition DeclBase.h:1017
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:936
friend class DeclContext
Definition DeclBase.h:260
Kind getKind() const
Definition DeclBase.h:451
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:782
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL)
Definition Decl.h:802
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:114
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:2071
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2440
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition Decl.h:2508
bool isInstantiatedFromMemberTemplate() const
Definition Decl.h:2505
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
spec_iterator spec_end() const
CommonBase * newCommon(ASTContext &C) const override
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D)
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
spec_range specializations() const
SpecIterator< FunctionTemplateSpecializationInfo > spec_iterator
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
bool isCompatibleWithDefinition() const
const FunctionTemplateDecl * getMostRecentDecl() const
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
void addSpecialization(FunctionTemplateSpecializationInfo *Info, llvm::FoldingSetInsertToken InsertToken)
Add a specialization of this function template.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
void Profile(llvm::FoldingSetNodeID &ID)
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
Provides information a specialization of a member of a class template, which may be a member function...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
TemplateParamObjectDecl * getFirstDecl()
This represents a decl that may have a name.
Definition Decl.h:276
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:288
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
const DefArgStorage & getDefaultArgStorage() const
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
static bool classofKind(Kind K)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the associated-constraints of this template parameter.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
static bool classof(const Decl *D)
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
bool hasPlaceholderTypeConstraint() const
Determine whether this non-type template parameter's type has a placeholder with a type-constraint.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setPlaceholderTypeConstraint(Expr *E)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition TypeBase.h:938
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, llvm::FoldingSetInsertToken InsertToken)
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
redeclarable_base::redecl_iterator redecl_iterator
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
const RedeclarableTemplateDecl * getCanonicalDecl() const
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redeclarable_base::redecl_range redecl_range
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
static bool classof(const Decl *D)
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
static bool classofKind(Kind K)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void setMemberSpecialization()
Note that this member template is a specialization.
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getNextRedeclaration() const
RedeclarableTemplateDecl * getPreviousDecl()
llvm::iterator_range< redecl_iterator > redecl_range
RedeclarableTemplateDecl * getMostRecentDecl()
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
TagTypeKind TagKind
Definition Decl.h:3873
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3964
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:3839
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:3665
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL=SourceLocation())
Definition Decl.h:3680
A container of type source information.
Definition TypeBase.h:8417
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2980
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9299
A set of unresolved declarations.
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T)
Definition Decl.h:720
QualType getType() const
Definition Decl.h:725
Represents a variable declaration or definition.
Definition Decl.h:934
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition Decl.cpp:2241
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:2764
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
void AddSpecialization(VarTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
SpecIterator< VarTemplateSpecializationDecl > spec_iterator
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
spec_range specializations() const
void setMemberSpecialization()
Note that this member template is a specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplatePartialSpecializationDecl * getMostRecentDecl()
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...
static bool classof(const Decl *D)
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this variable template specialization is actually an instantiation of the given variable te...
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
void setInstantiationOf(VarTemplateDecl *TemplDecl)
Note that this variable template specialization is an instantiation of the given variable template.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this variable template specialization is an instantiation of a template (rather than an explicit s...
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
VarTemplateSpecializationDecl * getMostRecentDecl()
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition Specifiers.h:216
@ 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:78
@ 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:252
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:498
@ FunctionTemplate
The name was classified as a function template name.
Definition Sema.h:580
@ Concept
The name was classified as a concept name.
Definition Sema.h:584
@ VarTemplate
The name was classified as a variable template name.
Definition Sema.h:578
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:192
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:202
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:195
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:6032
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition Specifiers.h:223
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 ...