clang 23.0.0git
DeclTemplate.h
Go to the documentation of this file.
1//===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the C++ template declaration subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15#define LLVM_CLANG_AST_DECLTEMPLATE_H
16
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclBase.h"
21#include "clang/AST/DeclCXX.h"
25#include "clang/AST/Type.h"
26#include "clang/Basic/LLVM.h"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/FoldingSet.h"
32#include "llvm/ADT/PointerIntPair.h"
33#include "llvm/ADT/PointerUnion.h"
34#include "llvm/ADT/iterator.h"
35#include "llvm/ADT/iterator_range.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/TrailingObjects.h"
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42#include <iterator>
43#include <optional>
44#include <utility>
45
46namespace clang {
47
51class Expr;
53class IdentifierInfo;
55class TemplateDecl;
58class ConceptDecl;
60class VarTemplateDecl;
62
63/// Stores a template parameter of any kind.
65 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
67
69
70/// Stores a list of template parameters for a TemplateDecl and its
71/// derived classes.
73 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
74 Expr *> {
75 /// The template argument list of the template parameter list.
76 mutable TemplateArgument *InjectedArgs = nullptr;
77
78 /// The location of the 'template' keyword.
79 SourceLocation TemplateLoc;
80
81 /// The locations of the '<' and '>' angle brackets.
82 SourceLocation LAngleLoc, RAngleLoc;
83
84 /// The number of template parameters in this template
85 /// parameter list.
86 unsigned NumParams : 29;
87
88 /// Whether this template parameter list contains an unexpanded parameter
89 /// pack.
90 LLVM_PREFERRED_TYPE(bool)
91 unsigned ContainsUnexpandedParameterPack : 1;
92
93 /// Whether this template parameter list has a requires clause.
94 LLVM_PREFERRED_TYPE(bool)
95 unsigned HasRequiresClause : 1;
96
97 /// Whether any of the template parameters has constrained-parameter
98 /// constraint-expression.
99 LLVM_PREFERRED_TYPE(bool)
100 unsigned HasConstrainedParameters : 1;
101
102protected:
104 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
105 SourceLocation RAngleLoc, Expr *RequiresClause);
106
107 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
108 return NumParams;
109 }
110
111 size_t numTrailingObjects(OverloadToken<Expr *>) const {
112 return HasRequiresClause ? 1 : 0;
113 }
114
115public:
116 template <size_t N, bool HasRequiresClause>
119
121 SourceLocation TemplateLoc,
122 SourceLocation LAngleLoc,
124 SourceLocation RAngleLoc,
125 Expr *RequiresClause);
126
127 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
128
129 /// Iterates through the template parameters in this list.
130 using iterator = NamedDecl **;
131
132 /// Iterates through the template parameters in this list.
133 using const_iterator = NamedDecl * const *;
134
135 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
136 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
137 iterator end() { return begin() + NumParams; }
138 const_iterator end() const { return begin() + NumParams; }
139
140 unsigned size() const { return NumParams; }
141 bool empty() const { return NumParams == 0; }
142
145
146 NamedDecl* getParam(unsigned Idx) {
147 assert(Idx < size() && "Template parameter index out-of-range");
148 return begin()[Idx];
149 }
150 const NamedDecl* getParam(unsigned Idx) const {
151 assert(Idx < size() && "Template parameter index out-of-range");
152 return begin()[Idx];
153 }
154
155 /// Returns the minimum number of arguments needed to form a
156 /// template specialization.
157 ///
158 /// This may be fewer than the number of template parameters, if some of
159 /// the parameters have default arguments or if there is a parameter pack.
160 unsigned getMinRequiredArguments() const;
161
162 /// Get the depth of this template parameter list in the set of
163 /// template parameter lists.
164 ///
165 /// The first template parameter list in a declaration will have depth 0,
166 /// the second template parameter list will have depth 1, etc.
167 unsigned getDepth() const;
168
169 /// Determine whether this template parameter list contains an
170 /// unexpanded parameter pack.
172
173 /// Determine whether this template parameter list contains a parameter pack.
174 bool hasParameterPack() const {
175 for (const NamedDecl *P : asArray())
176 if (P->isParameterPack())
177 return true;
178 return false;
179 }
180
181 /// The constraint-expression of the associated requires-clause.
183 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
184 }
185
186 /// The constraint-expression of the associated requires-clause.
187 const Expr *getRequiresClause() const {
188 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
189 }
190
191 /// \brief All associated constraints derived from this template parameter
192 /// list, including the requires clause and any constraints derived from
193 /// constrained-parameters.
194 ///
195 /// The constraints in the resulting list are to be treated as if in a
196 /// conjunction ("and").
199
201
202 /// Get the template argument list of the template parameter list.
204 getInjectedTemplateArgs(const ASTContext &Context) const;
205
206 SourceLocation getTemplateLoc() const { return TemplateLoc; }
207 SourceLocation getLAngleLoc() const { return LAngleLoc; }
208 SourceLocation getRAngleLoc() const { return RAngleLoc; }
209
210 SourceRange getSourceRange() const LLVM_READONLY {
211 return SourceRange(TemplateLoc, RAngleLoc);
212 }
213
214 void print(raw_ostream &Out, const ASTContext &Context,
215 bool OmitTemplateKW = false) const;
216 void print(raw_ostream &Out, const ASTContext &Context,
217 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
218
220 const TemplateParameterList *TPL,
221 unsigned Idx);
222};
223
224/// Stores a list of template parameters and the associated
225/// requires-clause (if any) for a TemplateDecl and its derived classes.
226/// Suitable for creating on the stack.
227template <size_t N, bool HasRequiresClause>
229 : public TemplateParameterList::FixedSizeStorageOwner {
230 typename TemplateParameterList::FixedSizeStorage<
231 NamedDecl *, Expr *>::with_counts<
232 N, HasRequiresClause ? 1u : 0u
233 >::type storage;
234
235public:
237 SourceLocation TemplateLoc,
238 SourceLocation LAngleLoc,
240 SourceLocation RAngleLoc,
241 Expr *RequiresClause)
242 : FixedSizeStorageOwner(
243 (assert(N == Params.size()),
244 assert(HasRequiresClause == (RequiresClause != nullptr)),
245 new (static_cast<void *>(&storage)) TemplateParameterList(C,
246 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
247};
248
249/// A template argument list.
250class TemplateArgumentList final
251 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
252 /// The number of template arguments in this template
253 /// argument list.
254 unsigned NumArguments;
255
256 // Constructs an instance with an internal Argument list, containing
257 // a copy of the Args array. (Called by CreateCopy)
258 TemplateArgumentList(ArrayRef<TemplateArgument> Args);
259
260public:
262
263 TemplateArgumentList(const TemplateArgumentList &) = delete;
264 TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
265
266 /// Create a new template argument list that copies the given set of
267 /// template arguments.
268 static TemplateArgumentList *CreateCopy(ASTContext &Context,
270
271 /// Retrieve the template argument at a given index.
272 const TemplateArgument &get(unsigned Idx) const {
273 assert(Idx < NumArguments && "Invalid template argument index");
274 return data()[Idx];
275 }
276
277 /// Retrieve the template argument at a given index.
278 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
279
280 /// Produce this as an array ref.
282 return getTrailingObjects(size());
283 }
284
285 /// Retrieve the number of template arguments in this
286 /// template argument list.
287 unsigned size() const { return NumArguments; }
288
289 /// Retrieve a pointer to the template argument list.
290 const TemplateArgument *data() const { return getTrailingObjects(); }
291};
292
294
295/// Storage for a default argument. This is conceptually either empty, or an
296/// argument value, or a pointer to a previous declaration that had a default
297/// argument.
298///
299/// However, this is complicated by modules: while we require all the default
300/// arguments for a template to be equivalent, there may be more than one, and
301/// we need to track all the originating parameters to determine if the default
302/// argument is visible.
303template<typename ParmDecl, typename ArgType>
305 /// Storage for both the value *and* another parameter from which we inherit
306 /// the default argument. This is used when multiple default arguments for a
307 /// parameter are merged together from different modules.
308 struct Chain {
309 ParmDecl *PrevDeclWithDefaultArg;
310 ArgType Value;
311 };
312 static_assert(sizeof(Chain) == sizeof(void *) * 2,
313 "non-pointer argument type?");
314
315 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
316
317 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
318 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
319 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
320 Parm = Prev;
321 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
322 "should only be one level of indirection");
323 return Parm;
324 }
325
326public:
327 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
328
329 /// Determine whether there is a default argument for this parameter.
330 bool isSet() const { return !ValueOrInherited.isNull(); }
331
332 /// Determine whether the default argument for this parameter was inherited
333 /// from a previous declaration of the same entity.
334 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
335
336 /// Get the default argument's value. This does not consider whether the
337 /// default argument is visible.
338 ArgType get() const {
339 const DefaultArgStorage *Storage = this;
340 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
341 Storage = &Prev->getDefaultArgStorage();
342 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
343 return C->Value;
344 return cast<ArgType>(Storage->ValueOrInherited);
345 }
346
347 /// Get the parameter from which we inherit the default argument, if any.
348 /// This is the parameter on which the default argument was actually written.
349 const ParmDecl *getInheritedFrom() const {
350 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
351 return D;
352 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
353 return C->PrevDeclWithDefaultArg;
354 return nullptr;
355 }
356
357 /// Set the default argument.
358 void set(ArgType Arg) {
359 assert(!isSet() && "default argument already set");
360 ValueOrInherited = Arg;
361 }
362
363 /// Set that the default argument was inherited from another parameter.
364 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
365 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
366 if (!isSet())
367 ValueOrInherited = InheritedFrom;
368 else if ([[maybe_unused]] auto *D =
369 dyn_cast<ParmDecl *>(ValueOrInherited)) {
370 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
371 ValueOrInherited =
372 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
373 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
374 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
375 InheritedFrom));
376 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
377 } else
378 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
379 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
380 }
381
382 /// Remove the default argument, even if it was inherited.
383 void clear() {
384 ValueOrInherited = ArgType();
385 }
386};
387
388//===----------------------------------------------------------------------===//
389// Kinds of Templates
390//===----------------------------------------------------------------------===//
391
392/// \brief The base class of all kinds of template declarations (e.g.,
393/// class, function, etc.).
394///
395/// The TemplateDecl class stores the list of template parameters and a
396/// reference to the templated scoped declaration: the underlying AST node.
397class TemplateDecl : public NamedDecl {
398 void anchor() override;
399
400protected:
401 // Construct a template decl with name, parameters, and templated element.
404
405 // Construct a template decl with the given name and parameters.
406 // Used when there is no templated element (e.g., for tt-params).
408 TemplateParameterList *Params)
409 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
410
411public:
412 friend class ASTDeclReader;
413 friend class ASTDeclWriter;
414
415 /// Get the list of template parameters
419
420 /// \brief Get the total constraint-expression associated with this template,
421 /// including constraint-expressions derived from the requires-clause,
422 /// trailing requires-clause (for functions and methods) and constrained
423 /// template parameters.
426
427 bool hasAssociatedConstraints() const;
428
429 /// Get the underlying, templated declaration.
431
432 // Should a specialization behave like an alias for another type.
433 bool isTypeAlias() const;
434
435 // Implement isa/cast/dyncast/etc.
436 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
437
438 static bool classofKind(Kind K) {
439 return K >= firstTemplate && K <= lastTemplate;
440 }
441
442 SourceRange getSourceRange() const override LLVM_READONLY {
443 return SourceRange(getTemplateParameters()->getTemplateLoc(),
444 TemplatedDecl->getSourceRange().getEnd());
445 }
446
447protected:
450
451public:
453 TemplateParams = TParams;
454 }
455
456 /// Initialize the underlying templated declaration.
457 void init(NamedDecl *NewTemplatedDecl) {
458 if (TemplatedDecl)
459 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
460 else
461 TemplatedDecl = NewTemplatedDecl;
462 }
463};
464
465/// Provides information about a function template specialization,
466/// which is a FunctionDecl that has been explicitly specialization or
467/// instantiated from a function template.
468class FunctionTemplateSpecializationInfo final
469 : public llvm::FoldingSetNode,
470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
471 MemberSpecializationInfo *> {
472 /// The function template specialization that this structure describes and a
473 /// flag indicating if the function is a member specialization.
474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
475
476 /// The function template from which this function template
477 /// specialization was generated.
478 ///
479 /// The three bits contain the TemplateSpecializationKind.
480 llvm::PointerIntPair<FunctionTemplateDecl *, 3> Template;
481
482public:
483 /// The template arguments used to produce the function template
484 /// specialization from the function template.
486
487 // The template parameters if this is an explicit specialization.
488 /// FIXME: Normally null; tail-allocate this.
490
491 /// The template arguments as written in the sources, if provided.
492 /// FIXME: Normally null; tail-allocate this.
494
495 /// The point at which this function template specialization was
496 /// first instantiated.
498
499private:
500 FunctionTemplateSpecializationInfo(
501 FunctionDecl *FD, FunctionTemplateDecl *Template,
504 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
506 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
508 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
510 assert(TemplateParameters == nullptr || TSK == TSK_ExplicitSpecialization);
511 if (MSInfo)
512 getTrailingObjects()[0] = MSInfo;
513 }
514
515 size_t numTrailingObjects() const { return Function.getInt(); }
516
517public:
519
520 static FunctionTemplateSpecializationInfo *
524 const TemplateArgumentListInfo *TemplateArgsAsWritten,
526
527 /// Retrieve the declaration of the function template specialization.
528 FunctionDecl *getFunction() const { return Function.getPointer(); }
529
530 /// Retrieve the template from which this function was specialized.
531 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
532
533 /// Determine what kind of template specialization this is.
535 return (TemplateSpecializationKind)(Template.getInt() + 1);
536 }
537
541
542 /// True if this declaration is an explicit specialization,
543 /// explicit instantiation declaration, or explicit instantiation
544 /// definition.
549
550 /// Set the template specialization kind.
552 assert(TSK != TSK_Undeclared &&
553 "Cannot encode TSK_Undeclared for a function template specialization");
554 Template.setInt(TSK - 1);
555 }
556
557 /// Retrieve the first point of instantiation of this function
558 /// template specialization.
559 ///
560 /// The point of instantiation may be an invalid source location if this
561 /// function has yet to be instantiated.
565
566 /// Set the (first) point of instantiation of this function template
567 /// specialization.
571
572 /// Get the specialization info if this function template specialization is
573 /// also a member specialization:
574 ///
575 /// \code
576 /// template<typename> struct A {
577 /// template<typename> void f();
578 /// template<> void f<int>();
579 /// };
580 /// \endcode
581 ///
582 /// Here, A<int>::f<int> is a function template specialization that is
583 /// an explicit specialization of A<int>::f, but it's also a member
584 /// specialization (an implicit instantiation in this case) of A::f<int>.
585 /// Further:
586 ///
587 /// \code
588 /// template<> template<> void A<int>::f<int>() {}
589 /// \endcode
590 ///
591 /// ... declares a function template specialization that is an explicit
592 /// specialization of A<int>::f, and is also an explicit member
593 /// specialization of A::f<int>.
594 ///
595 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
596 /// need not be the same as that returned by getTemplateSpecializationKind(),
597 /// and represents the relationship between the function and the class-scope
598 /// explicit specialization in the original templated class -- whereas our
599 /// TemplateSpecializationKind represents the relationship between the
600 /// function and the function template, and should always be
601 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
603 return numTrailingObjects() ? getTrailingObjects()[0] : nullptr;
604 }
605
606 void Profile(llvm::FoldingSetNodeID &ID) {
607 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
608 }
609
610 static void
611 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
612 const ASTContext &Context) {
613 ID.AddInteger(TemplateArgs.size());
614 for (const TemplateArgument &TemplateArg : TemplateArgs)
615 TemplateArg.Profile(ID, Context);
616 }
617};
618
619/// Provides information a specialization of a member of a class
620/// template, which may be a member function, static data member,
621/// member class or member enumeration.
623 // The member declaration from which this member was instantiated, and the
624 // manner in which the instantiation occurred (in the lower three bits).
625 llvm::PointerIntPair<NamedDecl *, 3> MemberAndTSK;
626
627 // The point at which this member was first instantiated.
628 SourceLocation PointOfInstantiation;
629
630public:
631 explicit
634 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
635 assert(TSK != TSK_Undeclared &&
636 "Cannot encode undeclared template specializations for members");
637 }
638
639 /// Retrieve the member declaration from which this member was
640 /// instantiated.
641 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
642
643 /// Determine what kind of template specialization this is.
645 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
646 }
647
651
652 /// Set the template specialization kind.
654 assert(TSK != TSK_Undeclared &&
655 "Cannot encode undeclared template specializations for members");
656 MemberAndTSK.setInt(TSK - 1);
657 }
658
659 /// Retrieve the first point of instantiation of this member.
660 /// If the point of instantiation is an invalid location, then this member
661 /// has not yet been instantiated.
663 return PointOfInstantiation;
664 }
665
666 /// Set the first point of instantiation.
668 PointOfInstantiation = POI;
669 }
670};
671
672/// Provides information about a dependent function-template
673/// specialization declaration.
674///
675/// This is used for function templates explicit specializations declared
676/// within class templates:
677///
678/// \code
679/// template<typename> struct A {
680/// template<typename> void f();
681/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
682/// };
683/// \endcode
684///
685/// As well as dependent friend declarations naming function template
686/// specializations declared within class templates:
687///
688/// \code
689/// template <class T> void foo(T);
690/// template <class T> class A {
691/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
692/// };
693/// \endcode
694class DependentFunctionTemplateSpecializationInfo final
695 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
696 FunctionTemplateDecl *> {
697 friend TrailingObjects;
698
699 /// The number of candidates for the primary template.
700 unsigned NumCandidates;
701
702 DependentFunctionTemplateSpecializationInfo(
703 const UnresolvedSetImpl &Candidates,
704 const TemplateParameterList *TemplateParams,
705 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
706
707public:
708 // The template parameters if this is an explicit specialization.
710
711 /// The template arguments as written in the sources, if provided.
713
714 static DependentFunctionTemplateSpecializationInfo *
715 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
716 const TemplateParameterList *TemplateParams,
717 const TemplateArgumentListInfo *TemplateArgs);
718
719 /// Returns the candidates for the primary function template.
721 return getTrailingObjects(NumCandidates);
722 }
723};
724
725/// Declaration of a redeclarable template.
727 public Redeclarable<RedeclarableTemplateDecl>
728{
729 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
730
732 return getNextRedeclaration();
733 }
734
736 return getPreviousDecl();
737 }
738
740 return getMostRecentDecl();
741 }
742
743 void anchor() override;
744
745protected:
746 template <typename EntryType> struct SpecEntryTraits {
747 using DeclType = EntryType;
748
749 static DeclType *getDecl(EntryType *D) {
750 return D;
751 }
752
754 return D->getTemplateArgs().asArray();
755 }
756 };
757
758 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
759 typename DeclType = typename SETraits::DeclType>
761 : llvm::iterator_adaptor_base<
762 SpecIterator<EntryType, SETraits, DeclType>,
763 typename llvm::FoldingSetVector<EntryType>::iterator,
764 typename std::iterator_traits<typename llvm::FoldingSetVector<
765 EntryType>::iterator>::iterator_category,
766 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
767 SpecIterator() = default;
768 explicit SpecIterator(
769 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
770 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
771
772 DeclType *operator*() const {
773 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
774 }
775
776 DeclType *operator->() const { return **this; }
777 };
778
779 template <typename EntryType>
780 static SpecIterator<EntryType>
781 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
782 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
783 }
784
785 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
786
788 TemplateParameterList *TPL = nullptr) const;
789
790 template <class EntryType, typename... ProfileArguments>
792 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
793 void *&InsertPos, ProfileArguments... ProfileArgs);
794
795 template <class EntryType, typename... ProfileArguments>
797 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
798 void *&InsertPos, ProfileArguments... ProfileArgs);
799
800 template <class Derived, class EntryType>
801 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
802 EntryType *Entry, void *InsertPos);
803
804 struct CommonBase {
806
807 /// The template from which this was most
808 /// directly instantiated (or null).
809 ///
810 /// The boolean value indicates whether this template
811 /// was explicitly specialized.
812 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
814 };
815
816 /// Pointer to the common data shared by all declarations of this
817 /// template.
818 mutable CommonBase *Common = nullptr;
819
820 /// Retrieves the "common" pointer shared by all (re-)declarations of
821 /// the same template. Calling this routine may implicitly allocate memory
822 /// for the common pointer.
823 CommonBase *getCommonPtr() const;
824
825 virtual CommonBase *newCommon(ASTContext &C) const = 0;
826
827 // Construct a template decl with name, parameters, and templated element.
831 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
832
833public:
834 friend class ASTDeclReader;
835 friend class ASTDeclWriter;
836 friend class ASTReader;
837 template <class decl_type> friend class RedeclarableTemplate;
838
839 /// Retrieves the canonical declaration of this template.
841 return getFirstDecl();
842 }
844 return getFirstDecl();
845 }
846
847 /// Determines whether this template was a specialization of a
848 /// member template.
849 ///
850 /// In the following example, the function template \c X<int>::f and the
851 /// member template \c X<int>::Inner are member specializations.
852 ///
853 /// \code
854 /// template<typename T>
855 /// struct X {
856 /// template<typename U> void f(T, U);
857 /// template<typename U> struct Inner;
858 /// };
859 ///
860 /// template<> template<typename T>
861 /// void X<int>::f(int, T);
862 /// template<> template<typename T>
863 /// struct X<int>::Inner { /* ... */ };
864 /// \endcode
866 return getCommonPtr()->InstantiatedFromMember.getInt();
867 }
868
869 /// Note that this member template is a specialization.
871 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
872 "Only member templates can be member template specializations");
873 getCommonPtr()->InstantiatedFromMember.setInt(true);
874 }
875
876 /// Retrieve the member template from which this template was
877 /// instantiated, or nullptr if this template was not instantiated from a
878 /// member template.
879 ///
880 /// A template is instantiated from a member template when the member
881 /// template itself is part of a class template (or member thereof). For
882 /// example, given
883 ///
884 /// \code
885 /// template<typename T>
886 /// struct X {
887 /// template<typename U> void f(T, U);
888 /// };
889 ///
890 /// void test(X<int> x) {
891 /// x.f(1, 'a');
892 /// };
893 /// \endcode
894 ///
895 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
896 /// template
897 ///
898 /// \code
899 /// template<typename U> void X<int>::f(int, U);
900 /// \endcode
901 ///
902 /// which was itself created during the instantiation of \c X<int>. Calling
903 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
904 /// retrieve the FunctionTemplateDecl for the original template \c f within
905 /// the class template \c X<T>, i.e.,
906 ///
907 /// \code
908 /// template<typename T>
909 /// template<typename U>
910 /// void X<T>::f(T, U);
911 /// \endcode
915
917 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
918 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
919 }
920
921 /// Retrieve the "injected" template arguments that correspond to the
922 /// template parameters of this template.
923 ///
924 /// Although the C++ standard has no notion of the "injected" template
925 /// arguments for a template, the notion is convenient when
926 /// we need to perform substitutions inside the definition of a template.
928 getInjectedTemplateArgs(const ASTContext &Context) const {
930 }
931
933 using redecl_iterator = redeclarable_base::redecl_iterator;
934
941
942 // Implement isa/cast/dyncast/etc.
943 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
944
945 static bool classofKind(Kind K) {
946 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
947 }
948};
949
950template <> struct RedeclarableTemplateDecl::
951SpecEntryTraits<FunctionTemplateSpecializationInfo> {
953
957
962};
963
964/// Declaration of a template function.
966protected:
967 friend class FunctionDecl;
968
969 /// Data that is common to all of the declarations of a given
970 /// function template.
972 /// The function template specializations for this function
973 /// template, including explicit specializations and instantiations.
974 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
975
976 Common() = default;
977 };
978
984
985 CommonBase *newCommon(ASTContext &C) const override;
986
988 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
989 }
990
991 /// Retrieve the set of function template specializations of this
992 /// function template.
993 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
994 getSpecializations() const;
995
996 /// Add a specialization of this function template.
997 ///
998 /// \param InsertPos Insert position in the FoldingSetVector, must have been
999 /// retrieved by an earlier call to findSpecialization().
1001 void *InsertPos);
1002
1003public:
1004 friend class ASTDeclReader;
1005 friend class ASTDeclWriter;
1006
1007 /// Load any lazily-loaded specializations from the external source.
1008 void LoadLazySpecializations() const;
1009
1010 /// Get the underlying function declaration of the template.
1012 return static_cast<FunctionDecl *>(TemplatedDecl);
1013 }
1014
1015 /// Returns whether this template declaration defines the primary
1016 /// pattern.
1020
1021 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1022 // except this is per declaration, while the redeclarable field is
1023 // per chain. This indicates a template redeclaration which
1024 // is compatible with the definition, in the non-trivial case
1025 // where this is not already a definition.
1026 // This is only really needed for instantiating the definition of friend
1027 // function templates, which can have redeclarations in different template
1028 // contexts.
1029 // The bit is actually stored in the FunctionDecl for space efficiency
1030 // reasons.
1035
1036 /// Return the specialization with the provided arguments if it exists,
1037 /// otherwise return the insertion point.
1039 void *&InsertPos);
1040
1049
1050 /// Retrieve the previous declaration of this function template, or
1051 /// nullptr if no such declaration exists.
1053 return cast_or_null<FunctionTemplateDecl>(
1054 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1055 }
1057 return cast_or_null<FunctionTemplateDecl>(
1058 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1059 }
1060
1067 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1068 }
1069
1071 return cast_or_null<FunctionTemplateDecl>(
1073 }
1074
1076 using spec_range = llvm::iterator_range<spec_iterator>;
1077
1079 return spec_range(spec_begin(), spec_end());
1080 }
1081
1083 return makeSpecIterator(getSpecializations(), false);
1084 }
1085
1087 return makeSpecIterator(getSpecializations(), true);
1088 }
1089
1090 /// Return whether this function template is an abbreviated function template,
1091 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1092 bool isAbbreviated() const {
1093 // Since the invented template parameters generated from 'auto' parameters
1094 // are either appended to the end of the explicit template parameter list or
1095 // form a new template parameter list, we can simply observe the last
1096 // parameter to determine if such a thing happened.
1098 return TPL->getParam(TPL->size() - 1)->isImplicit();
1099 }
1100
1101 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1103
1104 /// Create a function template node.
1107 DeclarationName Name,
1108 TemplateParameterList *Params,
1109 NamedDecl *Decl);
1110
1111 /// Create an empty function template node.
1113 GlobalDeclID ID);
1114
1115 // Implement isa/cast/dyncast support
1116 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1117 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1118};
1119
1120//===----------------------------------------------------------------------===//
1121// Kinds of Template Parameters
1122//===----------------------------------------------------------------------===//
1123
1124/// Defines the position of a template parameter within a template
1125/// parameter list.
1126///
1127/// Because template parameter can be listed
1128/// sequentially for out-of-line template members, each template parameter is
1129/// given a Depth - the nesting of template parameter scopes - and a Position -
1130/// the occurrence within the parameter list.
1131/// This class is inheritedly privately by different kinds of template
1132/// parameters and is not part of the Decl hierarchy. Just a facility.
1134protected:
1135 enum { DepthWidth = 20, PositionWidth = 12 };
1136 unsigned Depth : DepthWidth;
1138
1139 TemplateParmPosition(int D, int P) {
1140 setDepth(D);
1141 setPosition(P);
1142 }
1143
1144public:
1146
1147 /// Get the nesting depth of the template parameter.
1148 unsigned getDepth() const { return Depth; }
1149 void setDepth(int D) {
1150 assert(D >= 0 && "The depth cannot be negative");
1151 assert(D < (1 << DepthWidth) && "The depth is too large");
1152 Depth = D;
1153 }
1154
1155 /// Get the position of the template parameter within its parameter list.
1156 unsigned getPosition() const { return Position; }
1157 void setPosition(int P) {
1158 assert(P >= 0 && "The position cannot be negative");
1159 assert(P < (1 << PositionWidth) && "The position is too large");
1160 Position = P;
1161 }
1162
1163 /// Get the index of the template parameter within its parameter list.
1164 unsigned getIndex() const { return Position; }
1165};
1166
1167/// Declaration of a template type parameter.
1168///
1169/// For example, "T" in
1170/// \code
1171/// template<typename T> class vector;
1172/// \endcode
1173class TemplateTypeParmDecl final : public TypeDecl,
1174 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1175 /// Sema creates these on the stack during auto type deduction.
1176 friend class Sema;
1177 friend TrailingObjects;
1178 friend class ASTDeclReader;
1179
1180 /// Whether this template type parameter was declaration with
1181 /// the 'typename' keyword.
1182 ///
1183 /// If false, it was declared with the 'class' keyword.
1184 bool Typename : 1;
1185
1186 /// Whether this template type parameter has a type-constraint construct.
1187 bool HasTypeConstraint : 1;
1188
1189 /// Whether the type constraint has been initialized. This can be false if the
1190 /// constraint was not initialized yet or if there was an error forming the
1191 /// type constraint.
1192 bool TypeConstraintInitialized : 1;
1193
1194 /// The number of type parameters in an expanded parameter pack, if any.
1195 UnsignedOrNone NumExpanded = std::nullopt;
1196
1197 /// The default template argument, if any.
1198 using DefArgStorage =
1200 DefArgStorage DefaultArgument;
1201
1202 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1203 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1204 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1205 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1206 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1207 NumExpanded(NumExpanded) {}
1208
1209public:
1210 static TemplateTypeParmDecl *
1211 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1212 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1213 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1214 UnsignedOrNone NumExpanded = std::nullopt);
1216 GlobalDeclID ID);
1218 GlobalDeclID ID,
1219 bool HasTypeConstraint);
1220
1221 /// Whether this template type parameter was declared with
1222 /// the 'typename' keyword.
1223 ///
1224 /// If not, it was either declared with the 'class' keyword or with a
1225 /// type-constraint (see hasTypeConstraint()).
1227 return Typename && !HasTypeConstraint;
1228 }
1229
1230 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1231
1232 /// Determine whether this template parameter has a default
1233 /// argument.
1234 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1235
1236 /// Retrieve the default argument, if any.
1238 static const TemplateArgumentLoc NoneLoc;
1239 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1240 }
1241
1242 /// Retrieves the location of the default argument declaration.
1244
1245 /// Determines whether the default argument was inherited
1246 /// from a previous declaration of this template.
1248 return DefaultArgument.isInherited();
1249 }
1250
1251 /// Set the default argument for this template parameter.
1252 void setDefaultArgument(const ASTContext &C,
1253 const TemplateArgumentLoc &DefArg);
1254
1255 /// Set that this default argument was inherited from another
1256 /// parameter.
1258 TemplateTypeParmDecl *Prev) {
1259 DefaultArgument.setInherited(C, Prev);
1260 }
1261
1262 /// Removes the default argument of this template parameter.
1264 DefaultArgument.clear();
1265 }
1266
1267 /// Set whether this template type parameter was declared with
1268 /// the 'typename' or 'class' keyword.
1269 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1270
1271 /// Retrieve the depth of the template parameter.
1272 unsigned getDepth() const;
1273
1274 /// Retrieve the index of the template parameter.
1275 unsigned getIndex() const;
1276
1277 /// Returns whether this is a parameter pack.
1278 bool isParameterPack() const;
1279
1280 /// Whether this parameter pack is a pack expansion.
1281 ///
1282 /// A template type template parameter pack can be a pack expansion if its
1283 /// type-constraint contains an unexpanded parameter pack.
1284 bool isPackExpansion() const {
1285 if (!isParameterPack())
1286 return false;
1287 if (const TypeConstraint *TC = getTypeConstraint())
1288 if (TC->hasExplicitTemplateArgs())
1289 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1290 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1291 return true;
1292 return false;
1293 }
1294
1295 /// Whether this parameter is a template type parameter pack that has a known
1296 /// list of different type-constraints at different positions.
1297 ///
1298 /// A parameter pack is an expanded parameter pack when the original
1299 /// parameter pack's type-constraint was itself a pack expansion, and that
1300 /// expansion has already been expanded. For example, given:
1301 ///
1302 /// \code
1303 /// template<typename ...Types>
1304 /// struct X {
1305 /// template<convertible_to<Types> ...Convertibles>
1306 /// struct Y { /* ... */ };
1307 /// };
1308 /// \endcode
1309 ///
1310 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1311 /// its type-constraint. When \c Types is supplied with template arguments by
1312 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1313 /// expanded parameter pack. For example, instantiating
1314 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1315 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1316 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1317 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1318
1319 /// Returns the type constraint associated with this template parameter (if
1320 /// any).
1322 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1323 }
1324
1326 Expr *ImmediatelyDeclaredConstraint,
1327 UnsignedOrNone ArgPackSubstIndex);
1328
1329 /// Determine whether this template parameter has a type-constraint.
1330 bool hasTypeConstraint() const {
1331 return HasTypeConstraint;
1332 }
1333
1334 /// \brief Get the associated-constraints of this template parameter.
1335 /// This will either be the immediately-introduced constraint or empty.
1336 ///
1337 /// Use this instead of getTypeConstraint for concepts APIs that
1338 /// accept an ArrayRef of constraint expressions.
1341 if (HasTypeConstraint)
1342 AC.emplace_back(getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1343 getTypeConstraint()->getArgPackSubstIndex());
1344 }
1345
1346 SourceRange getSourceRange() const override LLVM_READONLY;
1347
1348 // Implement isa/cast/dyncast/etc.
1349 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1350 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1351};
1352
1353/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1354/// e.g., "Size" in
1355/// @code
1356/// template<int Size> class array { };
1357/// @endcode
1358class NonTypeTemplateParmDecl final
1359 : public DeclaratorDecl,
1360 protected TemplateParmPosition,
1361 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1362 std::pair<QualType, TypeSourceInfo *>,
1363 Expr *> {
1364 friend class ASTDeclReader;
1365 friend TrailingObjects;
1366
1367 /// The default template argument, if any, and whether or not
1368 /// it was inherited.
1369 using DefArgStorage =
1371 DefArgStorage DefaultArgument;
1372
1373 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1374 // down here to save memory.
1375
1376 /// Whether this non-type template parameter is a parameter pack.
1377 bool ParameterPack;
1378
1379 /// Whether this non-type template parameter is an "expanded"
1380 /// parameter pack, meaning that its type is a pack expansion and we
1381 /// already know the set of types that expansion expands to.
1382 bool ExpandedParameterPack = false;
1383
1384 /// The number of types in an expanded parameter pack.
1385 unsigned NumExpandedTypes = 0;
1386
1387 size_t numTrailingObjects(
1388 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1389 return NumExpandedTypes;
1390 }
1391
1393 SourceLocation IdLoc, int D, int P,
1394 const IdentifierInfo *Id, QualType T,
1395 bool ParameterPack, TypeSourceInfo *TInfo)
1396 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1397 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1398
1399 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1400 SourceLocation IdLoc, int D, int P,
1401 const IdentifierInfo *Id, QualType T,
1402 TypeSourceInfo *TInfo,
1403 ArrayRef<QualType> ExpandedTypes,
1404 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1405
1406public:
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, bool ParameterPack, TypeSourceInfo *TInfo);
1411
1412 static NonTypeTemplateParmDecl *
1413 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1414 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1415 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1416 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1417
1418 static NonTypeTemplateParmDecl *
1419 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1420 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1421 GlobalDeclID ID,
1422 unsigned NumExpandedTypes,
1423 bool HasTypeConstraint);
1424
1430
1431 SourceRange getSourceRange() const override LLVM_READONLY;
1432
1433 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1434
1435 /// Determine whether this template parameter has a default
1436 /// argument.
1437 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1438
1439 /// Retrieve the default argument, if any.
1441 static const TemplateArgumentLoc NoneLoc;
1442 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1443 }
1444
1445 /// Retrieve the location of the default argument, if any.
1447
1448 /// Determines whether the default argument was inherited
1449 /// from a previous declaration of this template.
1451 return DefaultArgument.isInherited();
1452 }
1453
1454 /// Set the default argument for this template parameter, and
1455 /// whether that default argument was inherited from another
1456 /// declaration.
1457 void setDefaultArgument(const ASTContext &C,
1458 const TemplateArgumentLoc &DefArg);
1460 NonTypeTemplateParmDecl *Parm) {
1461 DefaultArgument.setInherited(C, Parm);
1462 }
1463
1464 /// Removes the default argument of this template parameter.
1465 void removeDefaultArgument() { DefaultArgument.clear(); }
1466
1467 /// Whether this parameter is a non-type template parameter pack.
1468 ///
1469 /// If the parameter is a parameter pack, the type may be a
1470 /// \c PackExpansionType. In the following example, the \c Dims parameter
1471 /// is a parameter pack (whose type is 'unsigned').
1472 ///
1473 /// \code
1474 /// template<typename T, unsigned ...Dims> struct multi_array;
1475 /// \endcode
1476 bool isParameterPack() const { return ParameterPack; }
1477
1478 /// Whether this parameter pack is a pack expansion.
1479 ///
1480 /// A non-type template parameter pack is a pack expansion if its type
1481 /// contains an unexpanded parameter pack. In this case, we will have
1482 /// built a PackExpansionType wrapping the type.
1483 bool isPackExpansion() const {
1484 return ParameterPack && getType()->getAs<PackExpansionType>();
1485 }
1486
1487 /// Whether this parameter is a non-type template parameter pack
1488 /// that has a known list of different types at different positions.
1489 ///
1490 /// A parameter pack is an expanded parameter pack when the original
1491 /// parameter pack's type was itself a pack expansion, and that expansion
1492 /// has already been expanded. For example, given:
1493 ///
1494 /// \code
1495 /// template<typename ...Types>
1496 /// struct X {
1497 /// template<Types ...Values>
1498 /// struct Y { /* ... */ };
1499 /// };
1500 /// \endcode
1501 ///
1502 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1503 /// which expands \c Types. When \c Types is supplied with template arguments
1504 /// by instantiating \c X, the instantiation of \c Values becomes an
1505 /// expanded parameter pack. For example, instantiating
1506 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1507 /// pack with expansion types \c int and \c unsigned int.
1508 ///
1509 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1510 /// return the expansion types.
1511 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1512
1513 /// Retrieves the number of expansion types in an expanded parameter
1514 /// pack.
1515 unsigned getNumExpansionTypes() const {
1516 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1517 return NumExpandedTypes;
1518 }
1519
1520 /// Retrieve a particular expansion type within an expanded parameter
1521 /// pack.
1522 QualType getExpansionType(unsigned I) const {
1523 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1524 auto TypesAndInfos =
1525 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1526 return TypesAndInfos[I].first;
1527 }
1528
1529 /// Retrieve a particular expansion type source info within an
1530 /// expanded parameter pack.
1532 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1533 auto TypesAndInfos =
1534 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1535 return TypesAndInfos[I].second;
1536 }
1537
1538 /// Return the constraint introduced by the placeholder type of this non-type
1539 /// template parameter (if any).
1541 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1542 nullptr;
1543 }
1544
1546 *getTrailingObjects<Expr *>() = E;
1547 }
1548
1549 /// Determine whether this non-type template parameter's type has a
1550 /// placeholder with a type-constraint.
1552 auto *AT = getType()->getContainedAutoType();
1553 return AT && AT->isConstrained();
1554 }
1555
1556 /// \brief Get the associated-constraints of this template parameter.
1557 /// This will either be a vector of size 1 containing the immediately-declared
1558 /// constraint introduced by the placeholder type, or an empty vector.
1559 ///
1560 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1561 /// concepts APIs that accept an ArrayRef of constraint expressions.
1565 AC.emplace_back(E);
1566 }
1567
1568 // Implement isa/cast/dyncast/etc.
1569 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1570 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1571};
1572
1573/// TemplateTemplateParmDecl - Declares a template template parameter,
1574/// e.g., "T" in
1575/// @code
1576/// template <template <typename> class T> class container { };
1577/// @endcode
1578/// A template template parameter is a TemplateDecl because it defines the
1579/// name of a template and the template parameters allowable for substitution.
1580class TemplateTemplateParmDecl final
1581 : public TemplateDecl,
1582 protected TemplateParmPosition,
1583 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1584 TemplateParameterList *> {
1585 /// The default template argument, if any.
1586 using DefArgStorage =
1588 DefArgStorage DefaultArgument;
1589
1590 LLVM_PREFERRED_TYPE(TemplateNameKind)
1591 unsigned ParameterKind : 3;
1592
1593 /// Whether this template template parameter was declaration with
1594 /// the 'typename' keyword.
1595 ///
1596 /// If false, it was declared with the 'class' keyword.
1597 LLVM_PREFERRED_TYPE(bool)
1598 unsigned Typename : 1;
1599
1600 /// Whether this parameter is a parameter pack.
1601 LLVM_PREFERRED_TYPE(bool)
1602 unsigned ParameterPack : 1;
1603
1604 /// Whether this template template parameter is an "expanded"
1605 /// parameter pack, meaning that it is a pack expansion and we
1606 /// already know the set of template parameters that expansion expands to.
1607 LLVM_PREFERRED_TYPE(bool)
1608 unsigned ExpandedParameterPack : 1;
1609
1610 /// The number of parameters in an expanded parameter pack.
1611 unsigned NumExpandedParams = 0;
1612
1613 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1614 bool ParameterPack, IdentifierInfo *Id,
1615 TemplateNameKind ParameterKind, bool Typename,
1616 TemplateParameterList *Params)
1617 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1618 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1619 Typename(Typename), ParameterPack(ParameterPack),
1620 ExpandedParameterPack(false) {}
1621
1622 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1623 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1624 bool Typename, TemplateParameterList *Params,
1626
1627 void anchor() override;
1628
1629public:
1630 friend class ASTDeclReader;
1631 friend class ASTDeclWriter;
1633
1634 static TemplateTemplateParmDecl *
1635 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1636 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1637 bool Typename, TemplateParameterList *Params);
1638
1639 static TemplateTemplateParmDecl *
1640 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1641 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1642 TemplateParameterList *Params,
1644
1645 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1646 GlobalDeclID ID);
1647 static TemplateTemplateParmDecl *
1648 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1649
1655
1656 /// Whether this template template parameter was declared with
1657 /// the 'typename' keyword.
1658 bool wasDeclaredWithTypename() const { return Typename; }
1659
1660 /// Set whether this template template parameter was declared with
1661 /// the 'typename' or 'class' keyword.
1662 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1663
1664 /// Whether this template template parameter is a template
1665 /// parameter pack.
1666 ///
1667 /// \code
1668 /// template<template <class T> ...MetaFunctions> struct Apply;
1669 /// \endcode
1670 bool isParameterPack() const { return ParameterPack; }
1671
1672 /// Whether this parameter pack is a pack expansion.
1673 ///
1674 /// A template template parameter pack is a pack expansion if its template
1675 /// parameter list contains an unexpanded parameter pack.
1676 bool isPackExpansion() const {
1677 return ParameterPack &&
1679 }
1680
1681 /// Whether this parameter is a template template parameter pack that
1682 /// has a known list of different template parameter lists at different
1683 /// positions.
1684 ///
1685 /// A parameter pack is an expanded parameter pack when the original parameter
1686 /// pack's template parameter list was itself a pack expansion, and that
1687 /// expansion has already been expanded. For exampe, given:
1688 ///
1689 /// \code
1690 /// template<typename...Types> struct Outer {
1691 /// template<template<Types> class...Templates> struct Inner;
1692 /// };
1693 /// \endcode
1694 ///
1695 /// The parameter pack \c Templates is a pack expansion, which expands the
1696 /// pack \c Types. When \c Types is supplied with template arguments by
1697 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1698 /// parameter pack.
1699 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1700
1701 /// Retrieves the number of expansion template parameters in
1702 /// an expanded parameter pack.
1704 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1705 return NumExpandedParams;
1706 }
1707
1708 /// Retrieve a particular expansion type within an expanded parameter
1709 /// pack.
1711 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1712 return getTrailingObjects()[I];
1713 }
1714
1715 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1716
1717 /// Determine whether this template parameter has a default
1718 /// argument.
1719 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1720
1721 /// Retrieve the default argument, if any.
1723 static const TemplateArgumentLoc NoneLoc;
1724 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1725 }
1726
1727 /// Retrieve the location of the default argument, if any.
1729
1730 /// Determines whether the default argument was inherited
1731 /// from a previous declaration of this template.
1733 return DefaultArgument.isInherited();
1734 }
1735
1736 /// Set the default argument for this template parameter, and
1737 /// whether that default argument was inherited from another
1738 /// declaration.
1739 void setDefaultArgument(const ASTContext &C,
1740 const TemplateArgumentLoc &DefArg);
1742 TemplateTemplateParmDecl *Prev) {
1743 DefaultArgument.setInherited(C, Prev);
1744 }
1745
1746 /// Removes the default argument of this template parameter.
1747 void removeDefaultArgument() { DefaultArgument.clear(); }
1748
1749 SourceRange getSourceRange() const override LLVM_READONLY {
1753 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1754 }
1755
1757 return static_cast<TemplateNameKind>(ParameterKind);
1758 }
1759
1765
1766 // Implement isa/cast/dyncast/etc.
1767 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1768 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1769};
1770
1771/// Represents the builtin template declaration which is used to
1772/// implement __make_integer_seq and other builtin templates. It serves
1773/// no real purpose beyond existing as a place to hold template parameters.
1774class BuiltinTemplateDecl : public TemplateDecl {
1776
1777 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1779
1780 void anchor() override;
1781
1782public:
1783 // Implement isa/cast/dyncast support
1784 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1785 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1786
1787 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1788 DeclarationName Name,
1789 BuiltinTemplateKind BTK) {
1790 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1791 }
1792
1793 SourceRange getSourceRange() const override LLVM_READONLY {
1794 return {};
1795 }
1796
1798
1799 bool isPackProducingBuiltinTemplate() const;
1800};
1802
1803/// Provides information about an explicit instantiation of a variable or class
1804/// template.
1806 /// The template arguments as written..
1808
1809 /// The location of the extern keyword.
1811
1812 /// The location of the template keyword.
1814
1816};
1817
1819 /// The list of template parameters
1821
1822 /// The template arguments as written.
1824
1826};
1827
1829 llvm::PointerUnion<ExplicitSpecializationInfo *,
1831
1832/// Represents a class template specialization, which refers to
1833/// a class template with a given set of template arguments.
1834///
1835/// Class template specializations represent both explicit
1836/// specialization of class templates, as in the example below, and
1837/// implicit instantiations of class templates.
1838///
1839/// \code
1840/// template<typename T> class array;
1841///
1842/// template<>
1843/// class array<bool> { }; // class template specialization array<bool>
1844/// \endcode
1846 public llvm::FoldingSetNode {
1847 /// Structure that stores information about a class template
1848 /// specialization that was instantiated from a class template partial
1849 /// specialization.
1850 struct SpecializedPartialSpecialization {
1851 /// The class template partial specialization from which this
1852 /// class template specialization was instantiated.
1853 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1854
1855 /// The template argument list deduced for the class template
1856 /// partial specialization itself.
1857 const TemplateArgumentList *TemplateArgs;
1858 };
1859
1860 /// The template that this specialization specializes
1861 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1862 SpecializedTemplate;
1863
1864 /// Further info for explicit template specialization/instantiation.
1865 /// Does not apply to implicit specializations.
1866 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1867
1868 /// The template arguments used to describe this specialization.
1869 const TemplateArgumentList *TemplateArgs;
1870
1871 /// The point where this template was instantiated (if any)
1872 SourceLocation PointOfInstantiation;
1873
1874 /// The kind of specialization this declaration refers to.
1875 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1876 unsigned SpecializationKind : 3;
1877
1878 /// Indicate that we have matched a parameter pack with a non pack
1879 /// argument, when the opposite match is also allowed.
1880 /// This needs to be cached as deduction is performed during declaration,
1881 /// and we need the information to be preserved so that it is consistent
1882 /// during instantiation.
1883 LLVM_PREFERRED_TYPE(bool)
1884 unsigned StrictPackMatch : 1;
1885
1886protected:
1888 DeclContext *DC, SourceLocation StartLoc,
1889 SourceLocation IdLoc,
1890 ClassTemplateDecl *SpecializedTemplate,
1892 bool StrictPackMatch,
1894
1896
1897public:
1898 friend class ASTDeclReader;
1899 friend class ASTDeclWriter;
1900
1902 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1903 SourceLocation StartLoc, SourceLocation IdLoc,
1904 ClassTemplateDecl *SpecializedTemplate,
1905 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1908 GlobalDeclID ID);
1909
1910 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1911 bool Qualified) const override;
1912
1917
1922
1923 /// Retrieve the template that this specialization specializes.
1925
1926 /// Retrieve the template arguments of the class template
1927 /// specialization.
1929 return *TemplateArgs;
1930 }
1931
1933 TemplateArgs = Args;
1934 }
1935
1936 /// Determine the kind of specialization that this
1937 /// declaration represents.
1939 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1940 }
1941
1945
1946 /// Is this an explicit specialization at class scope (within the class that
1947 /// owns the primary template)? For example:
1948 ///
1949 /// \code
1950 /// template<typename T> struct Outer {
1951 /// template<typename U> struct Inner;
1952 /// template<> struct Inner; // class-scope explicit specialization
1953 /// };
1954 /// \endcode
1959
1960 /// True if this declaration is an explicit specialization,
1961 /// explicit instantiation declaration, or explicit instantiation
1962 /// definition.
1967
1969 SpecializedTemplate = Specialized;
1970 }
1971
1973 SpecializationKind = TSK;
1974 }
1975
1976 bool hasStrictPackMatch() const { return StrictPackMatch; }
1977
1978 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1979
1980 /// Get the point of instantiation (if any), or null if none.
1982 return PointOfInstantiation;
1983 }
1984
1986 assert(Loc.isValid() && "point of instantiation must be valid!");
1987 PointOfInstantiation = Loc;
1988 }
1989
1990 /// If this class template specialization is an instantiation of
1991 /// a template (rather than an explicit specialization), return the
1992 /// class template or class template partial specialization from which it
1993 /// was instantiated.
1994 llvm::PointerUnion<ClassTemplateDecl *,
1998 return llvm::PointerUnion<ClassTemplateDecl *,
2000
2002 }
2003
2004 /// Retrieve the class template or class template partial
2005 /// specialization which was specialized by this.
2006 llvm::PointerUnion<ClassTemplateDecl *,
2009 if (const auto *PartialSpec =
2010 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2011 return PartialSpec->PartialSpecialization;
2012
2013 return cast<ClassTemplateDecl *>(SpecializedTemplate);
2014 }
2015
2016 /// Retrieve the set of template arguments that should be used
2017 /// to instantiate members of the class template or class template partial
2018 /// specialization from which this class template specialization was
2019 /// instantiated.
2020 ///
2021 /// \returns For a class template specialization instantiated from the primary
2022 /// template, this function will return the same template arguments as
2023 /// getTemplateArgs(). For a class template specialization instantiated from
2024 /// a class template partial specialization, this function will return the
2025 /// deduced template arguments for the class template partial specialization
2026 /// itself.
2028 if (const auto *PartialSpec =
2029 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2030 return *PartialSpec->TemplateArgs;
2031
2032 return getTemplateArgs();
2033 }
2034
2035 /// Note that this class template specialization is actually an
2036 /// instantiation of the given class template partial specialization whose
2037 /// template arguments have been deduced.
2039 const TemplateArgumentList *TemplateArgs) {
2040 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2041 "Already set to a class template partial specialization!");
2042 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2043 PS->PartialSpecialization = PartialSpec;
2044 PS->TemplateArgs = TemplateArgs;
2045 SpecializedTemplate = PS;
2046 }
2047
2048 /// Note that this class template specialization is an instantiation
2049 /// of the given class template.
2051 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2052 "Previously set to a class template partial specialization!");
2053 SpecializedTemplate = TemplDecl;
2054 }
2055
2056 /// Retrieve the template argument list as written in the sources,
2057 /// if any.
2059 if (const auto *Info = getExplicitSpecializationInfo())
2060 return Info->TemplateArgsAsWritten;
2061 if (const auto *Info = getExplicitInstantiationInfo())
2062 return Info->TemplateArgsAsWritten;
2063 return nullptr;
2064 }
2065
2066 /// Gets the explicit instantiation info, if present.
2068 return dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
2069 }
2070
2071 /// Sets the explicit instantiation info.
2073 SourceLocation ExternKeywordLoc, SourceLocation TemplateKeywordLoc,
2074 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten) {
2075 auto *Info = new (getASTContext()) ExplicitInstantiationInfo();
2076 Info->ExternKeywordLoc = ExternKeywordLoc;
2077 Info->TemplateKeywordLoc = TemplateKeywordLoc;
2078 Info->TemplateArgsAsWritten = TemplateArgsAsWritten;
2079 ExplicitInfo = Info;
2080 }
2081
2082 /// Gets the explicit specialization info, if present.
2084 return dyn_cast_if_present<ExplicitSpecializationInfo *>(ExplicitInfo);
2085 }
2086
2087 /// Sets the explicit specialization info.
2089 TemplateParameterList *TemplateParams,
2090 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten);
2091
2092 SourceRange getSourceRange() const override LLVM_READONLY;
2093
2094 void Profile(llvm::FoldingSetNodeID &ID) const {
2095 Profile(ID, TemplateArgs->asArray(), getASTContext());
2096 }
2097
2098 static void
2099 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2100 const ASTContext &Context) {
2101 ID.AddInteger(TemplateArgs.size());
2102 for (const TemplateArgument &TemplateArg : TemplateArgs)
2103 TemplateArg.Profile(ID, Context);
2104 }
2105
2106 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2107
2108 static bool classofKind(Kind K) {
2109 return K >= firstClassTemplateSpecialization &&
2110 K <= lastClassTemplateSpecialization;
2111 }
2112};
2113
2114class ClassTemplatePartialSpecializationDecl
2116 /// The class template partial specialization from which this
2117 /// class template partial specialization was instantiated.
2118 ///
2119 /// The boolean value will be true to indicate that this class template
2120 /// partial specialization was specialized at this level.
2121 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2122 InstantiatedFromMember;
2123
2124 mutable CanQualType CanonInjectedTST;
2125
2126 ClassTemplatePartialSpecializationDecl(
2127 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2129 const ASTTemplateArgumentListInfo *ArgsAsWritten,
2130 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2131 CanQualType CanonInjectedTST,
2132 ClassTemplatePartialSpecializationDecl *PrevDecl);
2133
2134 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2135 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2136 InstantiatedFromMember(nullptr, false) {}
2137
2138 void anchor() override;
2139
2140public:
2141 friend class ASTDeclReader;
2142 friend class ASTDeclWriter;
2143
2144 static ClassTemplatePartialSpecializationDecl *
2145 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2146 SourceLocation StartLoc, SourceLocation IdLoc,
2147 TemplateParameterList *Params,
2148 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
2149 ClassTemplateDecl *SpecializedTemplate,
2150 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2151 ClassTemplatePartialSpecializationDecl *PrevDecl);
2152
2153 static ClassTemplatePartialSpecializationDecl *
2155
2156 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2158 static_cast<ClassTemplateSpecializationDecl *>(
2159 this)->getMostRecentDecl());
2160 }
2161
2162 /// Get the list of template parameters
2164 auto *ExplicitSpecInfo = getExplicitSpecializationInfo();
2165 assert(ExplicitSpecInfo &&
2166 "A partial specialization is always an explicit specialization");
2167 return ExplicitSpecInfo->TemplateParams;
2168 }
2169
2170 /// \brief All associated constraints of this partial specialization,
2171 /// including the requires clause and any constraints derived from
2172 /// constrained-parameters.
2173 ///
2174 /// The constraints in the resulting list are to be treated as if in a
2175 /// conjunction ("and").
2180
2184
2185 /// Retrieve the member class template partial specialization from
2186 /// which this particular class template partial specialization was
2187 /// instantiated.
2188 ///
2189 /// \code
2190 /// template<typename T>
2191 /// struct Outer {
2192 /// template<typename U> struct Inner;
2193 /// template<typename U> struct Inner<U*> { }; // #1
2194 /// };
2195 ///
2196 /// Outer<float>::Inner<int*> ii;
2197 /// \endcode
2198 ///
2199 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2200 /// end up instantiating the partial specialization
2201 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2202 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2203 /// \c Outer<float>::Inner<U*>, this function would return
2204 /// \c Outer<T>::Inner<U*>.
2205 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2206 const auto *First =
2208 return First->InstantiatedFromMember.getPointer();
2209 }
2214
2216 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2218 First->InstantiatedFromMember.setPointer(PartialSpec);
2219 }
2220
2221 /// Determines whether this class template partial specialization
2222 /// template was a specialization of a member partial specialization.
2223 ///
2224 /// In the following example, the member template partial specialization
2225 /// \c X<int>::Inner<T*> is a member specialization.
2226 ///
2227 /// \code
2228 /// template<typename T>
2229 /// struct X {
2230 /// template<typename U> struct Inner;
2231 /// template<typename U> struct Inner<U*>;
2232 /// };
2233 ///
2234 /// template<> template<typename T>
2235 /// struct X<int>::Inner<T*> { /* ... */ };
2236 /// \endcode
2238 const auto *First =
2240 return First->InstantiatedFromMember.getInt();
2241 }
2242
2243 /// Note that this member template is a specialization.
2244 /// A partial specialization may be a member specialization even if it is not
2245 /// an instantiation of a member partial specialization.
2248 return First->InstantiatedFromMember.setInt(true);
2249 }
2250
2251 /// Retrieves the canonical injected specialization type for this partial
2252 /// specialization.
2255
2256 SourceRange getSourceRange() const override LLVM_READONLY;
2257
2258 void Profile(llvm::FoldingSetNodeID &ID) const {
2260 getASTContext());
2261 }
2262
2263 static void
2264 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2265 TemplateParameterList *TPL, const ASTContext &Context);
2266
2267 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2268
2269 static bool classofKind(Kind K) {
2270 return K == ClassTemplatePartialSpecialization;
2271 }
2272};
2273
2274/// Declaration of a class template.
2276protected:
2277 /// Data that is common to all of the declarations of a given
2278 /// class template.
2280 /// The class template specializations for this class
2281 /// template, including explicit specializations and instantiations.
2282 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2283
2284 /// The class template partial specializations for this class
2285 /// template.
2286 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2288
2289 /// The Injected Template Specialization Type for this declaration.
2291
2292 Common() = default;
2293 };
2294
2295 /// Retrieve the set of specializations of this class template.
2296 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2297 getSpecializations() const;
2298
2299 /// Retrieve the set of partial specializations of this class
2300 /// template.
2301 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2303
2306 NamedDecl *Decl)
2307 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2308
2309 CommonBase *newCommon(ASTContext &C) const override;
2310
2312 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2313 }
2314
2316
2317public:
2318
2319 friend class ASTDeclReader;
2320 friend class ASTDeclWriter;
2322
2323 /// Load any lazily-loaded specializations from the external source.
2324 void LoadLazySpecializations(bool OnlyPartial = false) const;
2325
2326 /// Get the underlying class declarations of the template.
2328 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2329 }
2330
2331 /// Returns whether this template declaration defines the primary
2332 /// class pattern.
2336
2337 /// \brief Create a class template node.
2340 DeclarationName Name,
2341 TemplateParameterList *Params,
2342 NamedDecl *Decl);
2343
2344 /// Create an empty class template node.
2346
2347 /// Return the specialization with the provided arguments if it exists,
2348 /// otherwise return the insertion point.
2350 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2351
2352 /// Insert the specified specialization knowing that it is not already
2353 /// in. InsertPos must be obtained from findSpecialization.
2354 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2355
2364
2365 /// Retrieve the previous declaration of this class template, or
2366 /// nullptr if no such declaration exists.
2368 return cast_or_null<ClassTemplateDecl>(
2369 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2370 }
2372 return cast_or_null<ClassTemplateDecl>(
2373 static_cast<const RedeclarableTemplateDecl *>(
2374 this)->getPreviousDecl());
2375 }
2376
2382 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2383 }
2384
2386 return cast_or_null<ClassTemplateDecl>(
2388 }
2389
2390 /// Return the partial specialization with the provided arguments if it
2391 /// exists, otherwise return the insertion point.
2394 TemplateParameterList *TPL, void *&InsertPos);
2395
2396 /// Insert the specified partial specialization knowing that it is not
2397 /// already in. InsertPos must be obtained from findPartialSpecialization.
2399 void *InsertPos);
2400
2401 /// Retrieve the partial specializations as an ordered list.
2404
2405 /// Find a class template partial specialization with the given
2406 /// type T.
2407 ///
2408 /// \param T a dependent type that names a specialization of this class
2409 /// template.
2410 ///
2411 /// \returns the class template partial specialization that exactly matches
2412 /// the type \p T, or nullptr if no such partial specialization exists.
2414
2415 /// Find a class template partial specialization which was instantiated
2416 /// from the given member partial specialization.
2417 ///
2418 /// \param D a member class template partial specialization.
2419 ///
2420 /// \returns the class template partial specialization which was instantiated
2421 /// from the given member partial specialization, or nullptr if no such
2422 /// partial specialization exists.
2426
2427 /// Retrieve the canonical template specialization type of the
2428 /// injected-class-name for this class template.
2429 ///
2430 /// The injected-class-name for a class template \c X is \c
2431 /// X<template-args>, where \c template-args is formed from the
2432 /// template arguments that correspond to the template parameters of
2433 /// \c X. For example:
2434 ///
2435 /// \code
2436 /// template<typename T, int N>
2437 /// struct array {
2438 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2439 /// };
2440 /// \endcode
2443
2445 using spec_range = llvm::iterator_range<spec_iterator>;
2446
2448 return spec_range(spec_begin(), spec_end());
2449 }
2450
2452 return makeSpecIterator(getSpecializations(), false);
2453 }
2454
2456 return makeSpecIterator(getSpecializations(), true);
2457 }
2458
2459 // Implement isa/cast/dyncast support
2460 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2461 static bool classofKind(Kind K) { return K == ClassTemplate; }
2462};
2463
2464/// Declaration of a friend template.
2465///
2466/// For example:
2467/// \code
2468/// template <typename T> class A {
2469/// friend class MyVector<T>; // not a friend template
2470/// template <typename U> friend class B; // not a friend template
2471/// template <typename U> friend class Foo<T>::Nested; // friend template
2472/// };
2473/// \endcode
2474///
2475/// \note This class is not currently in use. All of the above
2476/// will yield a FriendDecl, not a FriendTemplateDecl.
2477class FriendTemplateDecl : public Decl {
2478 virtual void anchor();
2479
2480public:
2481 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2482
2483private:
2484 // The number of template parameters; always non-zero.
2485 unsigned NumParams = 0;
2486
2487 // The parameter list.
2488 TemplateParameterList **Params = nullptr;
2489
2490 // The declaration that's a friend of this class.
2491 FriendUnion Friend;
2492
2493 // Location of the 'friend' specifier.
2494 SourceLocation FriendLoc;
2495
2496 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2497 TemplateParameterList **Params, unsigned NumParams,
2498 FriendUnion Friend, SourceLocation FriendLoc)
2499 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2500 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2501
2502 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2503
2504public:
2505 friend class ASTDeclReader;
2506
2507 static FriendTemplateDecl *
2508 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2510 SourceLocation FriendLoc);
2511
2512 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2513
2514 /// If this friend declaration names a templated type (or
2515 /// a dependent member type of a templated type), return that
2516 /// type; otherwise return null.
2518 return Friend.dyn_cast<TypeSourceInfo*>();
2519 }
2520
2521 /// If this friend declaration names a templated function (or
2522 /// a member function of a templated type), return that type;
2523 /// otherwise return null.
2525 return Friend.dyn_cast<NamedDecl*>();
2526 }
2527
2528 /// Retrieves the location of the 'friend' keyword.
2530 return FriendLoc;
2531 }
2532
2534 assert(i <= NumParams);
2535 return Params[i];
2536 }
2537
2538 unsigned getNumTemplateParameters() const {
2539 return NumParams;
2540 }
2541
2542 // Implement isa/cast/dyncast/etc.
2543 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2544 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2545};
2546
2547/// Declaration of an alias template.
2548///
2549/// For example:
2550/// \code
2551/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2552/// \endcode
2554protected:
2556
2562
2563 CommonBase *newCommon(ASTContext &C) const override;
2564
2566 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2567 }
2568
2569public:
2570 friend class ASTDeclReader;
2571 friend class ASTDeclWriter;
2572
2573 /// Get the underlying function declaration of the template.
2575 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2576 }
2577
2578
2587
2588 /// Retrieve the previous declaration of this function template, or
2589 /// nullptr if no such declaration exists.
2591 return cast_or_null<TypeAliasTemplateDecl>(
2592 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2593 }
2595 return cast_or_null<TypeAliasTemplateDecl>(
2596 static_cast<const RedeclarableTemplateDecl *>(
2597 this)->getPreviousDecl());
2598 }
2599
2601 return cast_or_null<TypeAliasTemplateDecl>(
2603 }
2604
2605 /// Create a function template node.
2608 DeclarationName Name,
2609 TemplateParameterList *Params,
2610 NamedDecl *Decl);
2611
2612 /// Create an empty alias template node.
2614 GlobalDeclID ID);
2615
2616 // Implement isa/cast/dyncast support
2617 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2618 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2619};
2620
2621/// Represents a variable template specialization, which refers to
2622/// a variable template with a given set of template arguments.
2623///
2624/// Variable template specializations represent both explicit
2625/// specializations of variable templates, as in the example below, and
2626/// implicit instantiations of variable templates.
2627///
2628/// \code
2629/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2630///
2631/// template<>
2632/// constexpr float pi<float>; // variable template specialization pi<float>
2633/// \endcode
2635 public llvm::FoldingSetNode {
2636
2637 /// Structure that stores information about a variable template
2638 /// specialization that was instantiated from a variable template partial
2639 /// specialization.
2640 struct SpecializedPartialSpecialization {
2641 /// The variable template partial specialization from which this
2642 /// variable template specialization was instantiated.
2643 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2644
2645 /// The template argument list deduced for the variable template
2646 /// partial specialization itself.
2647 const TemplateArgumentList *TemplateArgs;
2648 };
2649
2650 /// The template that this specialization specializes.
2651 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2652 SpecializedTemplate;
2653
2654 /// Further info for explicit template specialization/instantiation.
2655 /// Does not apply to implicit specializations.
2656 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2657
2658 /// The template arguments used to describe this specialization.
2659 const TemplateArgumentList *TemplateArgs;
2660
2661 /// The point where this template was instantiated (if any).
2662 SourceLocation PointOfInstantiation;
2663
2664 /// The kind of specialization this declaration refers to.
2665 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2666 unsigned SpecializationKind : 3;
2667
2668 /// Whether this declaration is a complete definition of the
2669 /// variable template specialization. We can't otherwise tell apart
2670 /// an instantiated declaration from an instantiated definition with
2671 /// no initializer.
2672 LLVM_PREFERRED_TYPE(bool)
2673 unsigned IsCompleteDefinition : 1;
2674
2675protected:
2677 SourceLocation StartLoc, SourceLocation IdLoc,
2678 VarTemplateDecl *SpecializedTemplate,
2679 QualType T, TypeSourceInfo *TInfo,
2680 StorageClass S,
2682
2683 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2684
2685public:
2686 friend class ASTDeclReader;
2687 friend class ASTDeclWriter;
2688 friend class VarDecl;
2689
2691 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2692 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2693 TypeSourceInfo *TInfo, StorageClass S,
2696 GlobalDeclID ID);
2697
2698 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2699 bool Qualified) const override;
2700
2702 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2704 }
2705
2706 /// Retrieve the template that this specialization specializes.
2708
2709 /// Retrieve the template arguments of the variable template
2710 /// specialization.
2711 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2712
2713 /// Determine the kind of specialization that this
2714 /// declaration represents.
2716 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2717 }
2718
2722
2727
2728 /// True if this declaration is an explicit specialization,
2729 /// explicit instantiation declaration, or explicit instantiation
2730 /// definition.
2735
2737 SpecializationKind = TSK;
2738 }
2739
2740 /// Get the point of instantiation (if any), or null if none.
2742 return PointOfInstantiation;
2743 }
2744
2746 assert(Loc.isValid() && "point of instantiation must be valid!");
2747 PointOfInstantiation = Loc;
2748 }
2749
2750 void setCompleteDefinition() { IsCompleteDefinition = true; }
2751
2752 /// If this variable template specialization is an instantiation of
2753 /// a template (rather than an explicit specialization), return the
2754 /// variable template or variable template partial specialization from which
2755 /// it was instantiated.
2756 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2759 return llvm::PointerUnion<VarTemplateDecl *,
2761
2763 }
2764
2765 /// Retrieve the variable template or variable template partial
2766 /// specialization which was specialized by this.
2767 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2769 if (const auto *PartialSpec =
2770 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2771 return PartialSpec->PartialSpecialization;
2772
2773 return cast<VarTemplateDecl *>(SpecializedTemplate);
2774 }
2775
2776 /// Retrieve the set of template arguments that should be used
2777 /// to instantiate the initializer of the variable template or variable
2778 /// template partial specialization from which this variable template
2779 /// specialization was instantiated.
2780 ///
2781 /// \returns For a variable template specialization instantiated from the
2782 /// primary template, this function will return the same template arguments
2783 /// as getTemplateArgs(). For a variable template specialization instantiated
2784 /// from a variable template partial specialization, this function will the
2785 /// return deduced template arguments for the variable template partial
2786 /// specialization itself.
2788 if (const auto *PartialSpec =
2789 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2790 return *PartialSpec->TemplateArgs;
2791
2792 return getTemplateArgs();
2793 }
2794
2795 /// Note that this variable template specialization is actually an
2796 /// instantiation of the given variable template partial specialization whose
2797 /// template arguments have been deduced.
2799 const TemplateArgumentList *TemplateArgs) {
2800 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2801 "Already set to a variable template partial specialization!");
2802 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2803 PS->PartialSpecialization = PartialSpec;
2804 PS->TemplateArgs = TemplateArgs;
2805 SpecializedTemplate = PS;
2806 }
2807
2808 /// Note that this variable template specialization is an instantiation
2809 /// of the given variable template.
2811 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2812 "Previously set to a variable template partial specialization!");
2813 SpecializedTemplate = TemplDecl;
2814 }
2815
2816 /// Retrieve the template argument list as written in the sources,
2817 /// if any.
2819 if (const auto *Info = getExplicitSpecializationInfo())
2820 return Info->TemplateArgsAsWritten;
2821 if (const auto *Info = getExplicitInstantiationInfo())
2822 return Info->TemplateArgsAsWritten;
2823 return nullptr;
2824 }
2825
2826 /// Gets the explicit instantiation info, if present.
2828 return dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
2829 }
2830
2831 /// Sets the explicit instantiation info.
2833 SourceLocation ExternKeywordLoc, SourceLocation TemplateKeywordLoc,
2834 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten) {
2835 auto *Info = new (getASTContext()) ExplicitInstantiationInfo();
2836 Info->ExternKeywordLoc = ExternKeywordLoc;
2837 Info->TemplateKeywordLoc = TemplateKeywordLoc;
2838 Info->TemplateArgsAsWritten = TemplateArgsAsWritten;
2839 ExplicitInfo = Info;
2840 }
2841
2842 /// Gets the explicit specialization info, if present.
2844 return dyn_cast_if_present<ExplicitSpecializationInfo *>(ExplicitInfo);
2845 }
2846
2847 /// Sets the explicit specialization info.
2849 TemplateParameterList *TemplateParams,
2850 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten);
2851
2852 SourceRange getSourceRange() const override LLVM_READONLY;
2853
2854 void Profile(llvm::FoldingSetNodeID &ID) const {
2855 Profile(ID, TemplateArgs->asArray(), getASTContext());
2856 }
2857
2858 static void Profile(llvm::FoldingSetNodeID &ID,
2859 ArrayRef<TemplateArgument> TemplateArgs,
2860 const ASTContext &Context) {
2861 ID.AddInteger(TemplateArgs.size());
2862 for (const TemplateArgument &TemplateArg : TemplateArgs)
2863 TemplateArg.Profile(ID, Context);
2864 }
2865
2866 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2867
2868 static bool classofKind(Kind K) {
2869 return K >= firstVarTemplateSpecialization &&
2870 K <= lastVarTemplateSpecialization;
2871 }
2872};
2873
2874class VarTemplatePartialSpecializationDecl
2876 /// The variable template partial specialization from which this
2877 /// variable template partial specialization was instantiated.
2878 ///
2879 /// The boolean value will be true to indicate that this variable template
2880 /// partial specialization was specialized at this level.
2881 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2882 InstantiatedFromMember;
2883
2884 VarTemplatePartialSpecializationDecl(
2885 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2887 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
2888 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2890
2891 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2892 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2893 Context),
2894 InstantiatedFromMember(nullptr, false) {}
2895
2896 void anchor() override;
2897
2898public:
2899 friend class ASTDeclReader;
2900 friend class ASTDeclWriter;
2901
2902 static VarTemplatePartialSpecializationDecl *
2903 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2905 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
2906 VarTemplateDecl *SpecializedTemplate, QualType T,
2907 TypeSourceInfo *TInfo, StorageClass S,
2909
2910 static VarTemplatePartialSpecializationDecl *
2912
2913 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2915 static_cast<VarTemplateSpecializationDecl *>(
2916 this)->getMostRecentDecl());
2917 }
2918
2919 /// Get the list of template parameters
2921 auto *ExplicitSpecInfo = getExplicitSpecializationInfo();
2922 assert(ExplicitSpecInfo &&
2923 "A partial specialization is always an explicit specialization");
2924 return ExplicitSpecInfo->TemplateParams;
2925 }
2926
2927 /// Get the template argument list of the template parameter list.
2929 getInjectedTemplateArgs(const ASTContext &Context) const {
2931 }
2932
2933 /// \brief All associated constraints of this partial specialization,
2934 /// including the requires clause and any constraints derived from
2935 /// constrained-parameters.
2936 ///
2937 /// The constraints in the resulting list are to be treated as if in a
2938 /// conjunction ("and").
2943
2947
2948 /// \brief Retrieve the member variable template partial specialization from
2949 /// which this particular variable template partial specialization was
2950 /// instantiated.
2951 ///
2952 /// \code
2953 /// template<typename T>
2954 /// struct Outer {
2955 /// template<typename U> U Inner;
2956 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2957 /// };
2958 ///
2959 /// template int* Outer<float>::Inner<int*>;
2960 /// \endcode
2961 ///
2962 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2963 /// end up instantiating the partial specialization
2964 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2965 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2966 /// \c Outer<float>::Inner<U*>, this function would return
2967 /// \c Outer<T>::Inner<U*>.
2968 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2969 const auto *First =
2971 return First->InstantiatedFromMember.getPointer();
2972 }
2973
2974 void
2975 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2977 First->InstantiatedFromMember.setPointer(PartialSpec);
2978 }
2979
2980 /// Determines whether this variable template partial specialization
2981 /// was a specialization of a member partial specialization.
2982 ///
2983 /// In the following example, the member template partial specialization
2984 /// \c X<int>::Inner<T*> is a member specialization.
2985 ///
2986 /// \code
2987 /// template<typename T>
2988 /// struct X {
2989 /// template<typename U> U Inner;
2990 /// template<typename U> U* Inner<U*> = (U*)(0);
2991 /// };
2992 ///
2993 /// template<> template<typename T>
2994 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2995 /// \endcode
2997 const auto *First =
2999 return First->InstantiatedFromMember.getInt();
3000 }
3001
3002 /// Note that this member template is a specialization.
3003 /// A partial specialization may be a member specialization even if it is not
3004 /// an instantiation of a member partial specialization.
3007 return First->InstantiatedFromMember.setInt(true);
3008 }
3009
3010 SourceRange getSourceRange() const override LLVM_READONLY;
3011
3012 void Profile(llvm::FoldingSetNodeID &ID) const {
3014 getASTContext());
3015 }
3016
3017 static void
3018 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3019 TemplateParameterList *TPL, const ASTContext &Context);
3020
3021 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3022
3023 static bool classofKind(Kind K) {
3024 return K == VarTemplatePartialSpecialization;
3025 }
3026};
3027
3028/// Declaration of a variable template.
3030protected:
3031 /// Data that is common to all of the declarations of a given
3032 /// variable template.
3034 /// The variable template specializations for this variable
3035 /// template, including explicit specializations and instantiations.
3036 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3037
3038 /// The variable template partial specializations for this variable
3039 /// template.
3040 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3042
3043 Common() = default;
3044 };
3045
3046 /// Retrieve the set of specializations of this variable template.
3047 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3048 getSpecializations() const;
3049
3050 /// Retrieve the set of partial specializations of this class
3051 /// template.
3052 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3054
3059
3060 CommonBase *newCommon(ASTContext &C) const override;
3061
3063 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3064 }
3065
3066public:
3067 friend class ASTDeclReader;
3068 friend class ASTDeclWriter;
3069
3070 /// Load any lazily-loaded specializations from the external source.
3071 void LoadLazySpecializations(bool OnlyPartial = false) const;
3072
3073 /// Get the underlying variable declarations of the template.
3075 return static_cast<VarDecl *>(TemplatedDecl);
3076 }
3077
3078 /// Returns whether this template declaration defines the primary
3079 /// variable pattern.
3083
3085
3086 /// Create a variable template node.
3089 TemplateParameterList *Params,
3090 VarDecl *Decl);
3091
3092 /// Create an empty variable template node.
3094
3095 /// Return the specialization with the provided arguments if it exists,
3096 /// otherwise return the insertion point.
3098 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3099
3100 /// Insert the specified specialization knowing that it is not already
3101 /// in. InsertPos must be obtained from findSpecialization.
3102 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3103
3110
3111 /// Retrieve the previous declaration of this variable template, or
3112 /// nullptr if no such declaration exists.
3114 return cast_or_null<VarTemplateDecl>(
3115 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3116 }
3118 return cast_or_null<VarTemplateDecl>(
3119 static_cast<const RedeclarableTemplateDecl *>(
3120 this)->getPreviousDecl());
3121 }
3122
3128 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3129 }
3130
3135
3136 /// Return the partial specialization with the provided arguments if it
3137 /// exists, otherwise return the insertion point.
3140 TemplateParameterList *TPL, void *&InsertPos);
3141
3142 /// Insert the specified partial specialization knowing that it is not
3143 /// already in. InsertPos must be obtained from findPartialSpecialization.
3145 void *InsertPos);
3146
3147 /// Retrieve the partial specializations as an ordered list.
3150
3151 /// Find a variable template partial specialization which was
3152 /// instantiated
3153 /// from the given member partial specialization.
3154 ///
3155 /// \param D a member variable template partial specialization.
3156 ///
3157 /// \returns the variable template partial specialization which was
3158 /// instantiated
3159 /// from the given member partial specialization, or nullptr if no such
3160 /// partial specialization exists.
3163
3165 using spec_range = llvm::iterator_range<spec_iterator>;
3166
3168 return spec_range(spec_begin(), spec_end());
3169 }
3170
3172 return makeSpecIterator(getSpecializations(), false);
3173 }
3174
3176 return makeSpecIterator(getSpecializations(), true);
3177 }
3178
3179 // Implement isa/cast/dyncast support
3180 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3181 static bool classofKind(Kind K) { return K == VarTemplate; }
3182};
3183
3184/// Declaration of a C++20 concept.
3185class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3186protected:
3188
3193public:
3195 DeclarationName Name,
3196 TemplateParameterList *Params,
3197 Expr *ConstraintExpr = nullptr);
3199
3201 return ConstraintExpr;
3202 }
3203
3204 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3205
3207
3208 SourceRange getSourceRange() const override LLVM_READONLY {
3209 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3210 ConstraintExpr ? ConstraintExpr->getEndLoc()
3211 : SourceLocation());
3212 }
3213
3214 bool isTypeConcept() const {
3215 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3216 }
3217
3220 }
3222 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3223 }
3224
3225 // Implement isa/cast/dyncast/etc.
3226 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3227 static bool classofKind(Kind K) { return K == Concept; }
3228
3229 friend class ASTReader;
3230 friend class ASTDeclReader;
3231 friend class ASTDeclWriter;
3232};
3233
3234// An implementation detail of ConceptSpecialicationExpr that holds the template
3235// arguments, so we can later use this to reconstitute the template arguments
3236// during constraint checking.
3237class ImplicitConceptSpecializationDecl final
3238 : public Decl,
3239 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3240 TemplateArgument> {
3241 unsigned NumTemplateArgs;
3242
3243 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3244 ArrayRef<TemplateArgument> ConvertedArgs);
3245 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3246
3247public:
3248 static ImplicitConceptSpecializationDecl *
3250 ArrayRef<TemplateArgument> ConvertedArgs);
3251 static ImplicitConceptSpecializationDecl *
3253 unsigned NumTemplateArgs);
3254
3256 return getTrailingObjects(NumTemplateArgs);
3257 }
3259
3260 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3261 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3262
3264 friend class ASTDeclReader;
3265};
3266
3267/// A template parameter object.
3268///
3269/// Template parameter objects represent values of class type used as template
3270/// arguments. There is one template parameter object for each such distinct
3271/// value used as a template argument across the program.
3272///
3273/// \code
3274/// struct A { int x, y; };
3275/// template<A> struct S;
3276/// S<A{1, 2}> s1;
3277/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3278/// \endcode
3279class TemplateParamObjectDecl : public ValueDecl,
3280 public Mergeable<TemplateParamObjectDecl>,
3281 public llvm::FoldingSetNode {
3282private:
3283 /// The value of this template parameter object.
3284 APValue Value;
3285
3286 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3287 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3288 T),
3289 Value(V) {}
3290
3291 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3292 const APValue &V);
3293 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3294 GlobalDeclID ID);
3295
3296 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3297 /// create these.
3298 friend class ASTContext;
3299 friend class ASTReader;
3300 friend class ASTDeclReader;
3301
3302public:
3303 /// Print this template parameter object in a human-readable format.
3304 void printName(llvm::raw_ostream &OS,
3305 const PrintingPolicy &Policy) const override;
3306
3307 /// Print this object as an equivalent expression.
3308 void printAsExpr(llvm::raw_ostream &OS) const;
3309 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3310
3311 /// Print this object as an initializer suitable for a variable of the
3312 /// object's type.
3313 void printAsInit(llvm::raw_ostream &OS) const;
3314 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3315
3316 const APValue &getValue() const { return Value; }
3317
3318 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3319 const APValue &V) {
3320 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3321 V.Profile(ID);
3322 }
3323 void Profile(llvm::FoldingSetNodeID &ID) {
3324 Profile(ID, getType(), getValue());
3325 }
3326
3327 TemplateParamObjectDecl *getCanonicalDecl() override {
3328 return getFirstDecl();
3329 }
3330 const TemplateParamObjectDecl *getCanonicalDecl() const {
3331 return getFirstDecl();
3332 }
3333
3334 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3335 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3336};
3337
3339 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3340 return PD;
3341 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3342 return PD;
3344}
3345
3347 auto *TD = dyn_cast<TemplateDecl>(D);
3348 return TD && (isa<ClassTemplateDecl>(TD) ||
3351 [&]() {
3352 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
3353 return TTP->templateParameterKind() == TNK_Type_template;
3354 return false;
3355 }())
3356 ? TD
3357 : nullptr;
3358}
3359
3360/// Check whether the template parameter is a pack expansion, and if so,
3361/// determine the number of parameters produced by that expansion. For instance:
3362///
3363/// \code
3364/// template<typename ...Ts> struct A {
3365/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3366/// };
3367/// \endcode
3368///
3369/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3370/// is not a pack expansion, so returns an empty Optional.
3372 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3373 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3374 return Num;
3375 }
3376
3377 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3378 if (NTTP->isExpandedParameterPack())
3379 return NTTP->getNumExpansionTypes();
3380 }
3381
3382 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3383 if (TTP->isExpandedParameterPack())
3384 return TTP->getNumExpansionTemplateParameters();
3385 }
3386
3387 return std::nullopt;
3388}
3389
3390/// Internal helper used by Subst* nodes to retrieve a parameter from the
3391/// AssociatedDecl, and the template argument substituted into it, if any.
3392std::tuple<NamedDecl *, TemplateArgument>
3393getReplacedTemplateParameter(Decl *D, unsigned Index);
3394
3395/// If we have a 'templated' declaration for a template, adjust 'D' to
3396/// refer to the actual template.
3397/// If we have an implicit instantiation, adjust 'D' to refer to template.
3398const Decl &adjustDeclToTemplate(const Decl &D);
3399
3400/// Represents an explicit instantiation of a template entity in source code.
3401///
3402/// \code
3403/// template void ns::foo<int>(int); // function template
3404/// extern template struct ns::S<int>; // class template (extern)
3405/// template int ns::bar<int>; // variable template
3406/// template void ns::S<int>::method(int); // member function
3407/// \endcode
3408class ExplicitInstantiationDecl final
3409 : public Decl,
3410 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3411 NestedNameSpecifierLoc,
3412 const ASTTemplateArgumentListInfo *> {
3413 friend class ASTDeclReader;
3414 friend class ASTDeclWriter;
3415 friend TrailingObjects;
3416
3417 /// The underlying specialization (low 3 bits: TSK).
3418 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3419
3420 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3421 /// Always non-null after construction.
3422 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3423 /// qualifier, template-name, and argument locations.
3424 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3425 /// - Function / variable templates: the declared type.
3426 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3427
3428 /// Location of the 'extern' keyword (invalid if not extern template).
3429 SourceLocation ExternLoc;
3430
3431 /// Location of the entity name (e.g., 'foo' in 'template void
3432 /// ns::foo<int>(int)').
3433 SourceLocation NameLoc;
3434
3435 enum TrailingFlags : unsigned {
3436 HasQualifierFlag = 1,
3437 HasArgsAsWrittenFlag = 2,
3438 };
3439
3440 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3441 return hasTrailingQualifier() ? 1 : 0;
3442 }
3443
3444 /// For class templates / nested classes, returns the TypeLoc encoding the
3445 /// entity (TemplateSpecializationTypeLoc or TagTypeLoc). For function /
3446 /// variable templates -- where TypeSourceInfo holds the declared type
3447 /// rather than the entity -- returns std::nullopt.
3448 std::optional<TypeLoc> getClassTypeLoc() const {
3450 return std::nullopt;
3451 if (auto *TSI = TypeAndFlags.getPointer())
3452 return TSI->getTypeLoc();
3453 return std::nullopt;
3454 }
3455
3456 /// Raw TypeSourceInfo pointer, needed by the serializer.
3457 TypeSourceInfo *getRawTypeSourceInfo() const {
3458 return TypeAndFlags.getPointer();
3459 }
3460
3461 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3462 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3464 return nullptr;
3465 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3466 }
3467
3468 ExplicitInstantiationDecl(
3469 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3470 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3471 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3472 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3473
3474 ExplicitInstantiationDecl(EmptyShell Empty)
3476
3477public:
3478 static ExplicitInstantiationDecl *
3479 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3480 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3481 NestedNameSpecifierLoc QualifierLoc,
3482 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3483 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3485
3486 static ExplicitInstantiationDecl *
3487 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3488
3489 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3490
3491 SourceRange getSourceRange() const override LLVM_READONLY;
3492 SourceLocation getEndLoc() const LLVM_READONLY;
3493
3494 SourceLocation getExternLoc() const { return ExternLoc; }
3496 SourceLocation getNameLoc() const { return NameLoc; }
3497
3498 /// The tag keyword (struct/class/union) location for class templates /
3499 /// nested classes; invalid for function / variable templates.
3501
3503 return TypeAndFlags.getInt() & HasQualifierFlag;
3504 }
3506 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3507 }
3508
3509 /// Returns the qualifier regardless of where it is stored.
3510 /// For class templates / nested classes, extracted from the class TypeLoc;
3511 /// for function / variable templates, from a trailing object.
3513
3514 /// Returns the number of explicit template arguments, or std::nullopt if
3515 /// this entity has no template argument list (e.g., nested classes).
3516 std::optional<unsigned> getNumTemplateArgs() const;
3517 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3520
3521 /// The declared type (return type or variable type) for function / variable
3522 /// templates. Null for class templates and nested classes.
3524
3526 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3527 }
3528
3529 bool isExternTemplate() const { return ExternLoc.isValid(); }
3530
3531 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3532 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3533};
3534
3535} // namespace clang
3536
3537#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:472
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TemplateNameKind enum.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
BuiltinTemplateKind getBuiltinTemplateKind() const
static BuiltinTemplateDecl * Create(const ASTContext &C, DeclContext *DC, DeclarationName Name, BuiltinTemplateKind BTK)
static bool classof(const Decl *D)
static bool classofKind(Kind K)
bool isPackProducingBuiltinTemplate() const
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CXXRecordDecl * getMostRecentDecl()
Definition DeclCXX.h:539
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition DeclCXX.cpp:2059
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:124
CXXRecordDecl * getDefinitionOrSelf() const
Definition DeclCXX.h:555
friend class DeclContext
Definition DeclCXX.h:266
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
ClassTemplateDecl * getMostRecentDecl()
spec_iterator spec_begin() const
spec_iterator spec_end() const
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
static bool classofKind(Kind K)
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
llvm::iterator_range< spec_iterator > spec_range
static bool classof(const Decl *D)
const ClassTemplateDecl * getMostRecentDecl() const
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
const ClassTemplateDecl * getCanonicalDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
SpecIterator< ClassTemplateSpecializationDecl > spec_iterator
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
void setCommonPtr(Common *C)
spec_range specializations() const
friend class TemplateDeclInstantiator
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setMemberSpecialization()
Note that this member template is a specialization.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setPointOfInstantiation(SourceLocation Loc)
void setExplicitInstantiationInfo(SourceLocation ExternKeywordLoc, SourceLocation TemplateKeywordLoc, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten)
Sets the explicit instantiation info.
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
const ExplicitSpecializationInfo * getExplicitSpecializationInfo() const
Gets the explicit specialization info, if present.
static bool classof(const Decl *D)
void setSpecializationKind(TemplateSpecializationKind TSK)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
void setExplicitSpecializationInfo(TemplateParameterList *TemplateParams, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten)
Sets the explicit specialization info.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
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...
const ExplicitInstantiationInfo * getExplicitInstantiationInfo() const
Gets the explicit instantiation info, if present.
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,...
ClassTemplateSpecializationDecl * getDefinitionOrSelf() const
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
void setDefinition(Expr *E)
Expr * getConstraintExpr() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
friend class ASTReader
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
friend class ASTDeclReader
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasDefinition() const
static bool classof(const Decl *D)
friend class ASTDeclWriter
const ConceptDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
virtual Decl * getPreviousDeclImpl()
Implementation of getPreviousDecl(), to be overridden by any subclass that has a redeclaration chain.
Definition DeclBase.h:1008
Kind
Lists the kind of concrete classes of Decl.
Definition DeclBase.h:89
virtual Decl * getNextRedeclarationImpl()
Returns the next redeclaration or itself if this is the only decl.
Definition DeclBase.h:1004
SourceLocation getLocation() const
Definition DeclBase.h:447
virtual Decl * getMostRecentDeclImpl()
Implementation of getMostRecentDecl(), to be overridden by any subclass that has a redeclaration chai...
Definition DeclBase.h:1012
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:931
friend class DeclContext
Definition DeclBase.h:260
Kind getKind() const
Definition DeclBase.h:450
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL)
Definition Decl.h:800
Storage for a default argument.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
bool isSet() const
Determine whether there is a default argument for this parameter.
ArgType get() const
Get the default argument's value.
void set(ArgType Arg)
Set the default argument.
void clear()
Remove the default argument, even if it was inherited.
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
const TemplateParameterList * TemplateParameters
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:112
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Declaration of a friend template.
static bool classof(const Decl *D)
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
NamedDecl * getFriendDecl() const
If this friend declaration names a templated function (or a member function of a templated type),...
TemplateParameterList * getTemplateParameterList(unsigned i) const
static bool classofKind(Kind K)
unsigned getNumTemplateParameters() const
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TypeSourceInfo * getFriendType() const
If this friend declaration names a templated type (or a dependent member type of a templated type),...
Represents a function declaration or definition.
Definition Decl.h:2018
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2306
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition Decl.h:2361
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
spec_iterator spec_end() const
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D)
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
spec_range specializations() const
SpecIterator< FunctionTemplateSpecializationInfo > spec_iterator
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const FunctionTemplateDecl * getMostRecentDecl() const
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
const TemplateParameterList * TemplateParameters
FIXME: Normally null; tail-allocate this.
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
void Profile(llvm::FoldingSetNodeID &ID)
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
Provides information a specialization of a member of a class template, which may be a member function...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
TemplateParamObjectDecl * getFirstDecl()
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
const DefArgStorage & getDefaultArgStorage() const
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
static bool classofKind(Kind K)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the associated-constraints of this template parameter.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
static bool classof(const Decl *D)
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
bool hasPlaceholderTypeConstraint() const
Determine whether this non-type template parameter's type has a placeholder with a type-constraint.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setPlaceholderTypeConstraint(Expr *E)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition TypeBase.h:937
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
redeclarable_base::redecl_iterator redecl_iterator
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
const RedeclarableTemplateDecl * getCanonicalDecl() const
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redeclarable_base::redecl_range redecl_range
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
static bool classof(const Decl *D)
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
static bool classofKind(Kind K)
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getNextRedeclaration() const
RedeclarableTemplateDecl * getPreviousDecl()
llvm::iterator_range< redecl_iterator > redecl_range
RedeclarableTemplateDecl * getMostRecentDecl()
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
TagTypeKind TagKind
Definition Decl.h:3728
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3819
A convenient class for passing around template argument information.
A template argument list.
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * TemplatedDecl
TemplateParameterList * TemplateParams
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
friend class ASTDeclReader
void setTemplateParameters(TemplateParameterList *TParams)
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static bool classof(const Decl *D)
friend class ASTDeclWriter
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
static bool classofKind(Kind K)
TemplateParamObjectDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const TemplateParamObjectDecl * getCanonicalDecl() const
void Profile(llvm::FoldingSetNodeID &ID)
const APValue & getValue() const
static bool classof(const Decl *D)
static void Profile(llvm::FoldingSetNodeID &ID, QualType T, const APValue &V)
friend class ASTContext
Only ASTContext::getTemplateParamObjectDecl and deserialization create these.
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
static bool classofKind(Kind K)
Stores a list of template parameters for a TemplateDecl and its derived classes.
const_iterator end() const
NamedDecl * getParam(unsigned Idx)
SourceRange getSourceRange() const LLVM_READONLY
const_iterator begin() const
friend class FixedSizeTemplateParameterListStorage
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
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:3694
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:3520
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL=SourceLocation())
Definition Decl.h:3535
A container of type source information.
Definition TypeBase.h:8411
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2961
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9270
A set of unresolved declarations.
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T)
Definition Decl.h:718
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:924
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition Decl.cpp:2240
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition Decl.cpp:2738
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
SpecIterator< VarTemplateSpecializationDecl > spec_iterator
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
spec_range specializations() const
void setMemberSpecialization()
Note that this member template is a specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplatePartialSpecializationDecl * getMostRecentDecl()
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
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...
const ExplicitSpecializationInfo * getExplicitSpecializationInfo() const
Gets the explicit specialization info, if present.
static bool classof(const Decl *D)
void setExplicitInstantiationInfo(SourceLocation ExternKeywordLoc, SourceLocation TemplateKeywordLoc, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten)
Sets the explicit instantiation info.
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)
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...
void setExplicitSpecializationInfo(TemplateParameterList *TemplateParams, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten)
Sets the explicit specialization info.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplateSpecializationDecl * getMostRecentDecl()
const ExplicitInstantiationInfo * getExplicitInstantiationInfo() const
Gets the explicit instantiation info, if present.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition Specifiers.h:215
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Definition Template.h:50
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition Decl.cpp:77
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
NamedDecl * getAsNamedDecl(TemplateParameter P)
bool isPackProducingBuiltinTemplateName(TemplateName N)
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h: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
@ ExplicitInstantiation
We are parsing an explicit instantiation.
Definition Parser.h:85
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition Builtins.h:491
@ FunctionTemplate
The name was classified as a function template name.
Definition Sema.h:587
@ Concept
The name was classified as a concept name.
Definition Sema.h:591
@ VarTemplate
The name was classified as a variable template name.
Definition Sema.h:585
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
const Decl & adjustDeclToTemplate(const Decl &D)
If we have a 'templated' declaration for a template, adjust 'D' to refer to the actual template.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition Specifiers.h:189
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:201
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
llvm::PointerUnion< ExplicitSpecializationInfo *, ExplicitInstantiationInfo * > SpecializationOrInstantiationInfo
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:5986
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition Specifiers.h:222
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>".
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.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written.
TemplateParameterList * TemplateParams
The list of template parameters.
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 ...