clang 21.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"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerIntPair.h"
32#include "llvm/ADT/PointerUnion.h"
33#include "llvm/ADT/iterator.h"
34#include "llvm/ADT/iterator_range.h"
35#include "llvm/Support/Casting.h"
36#include "llvm/Support/Compiler.h"
37#include "llvm/Support/TrailingObjects.h"
38#include <cassert>
39#include <cstddef>
40#include <cstdint>
41#include <iterator>
42#include <optional>
43#include <utility>
44
45namespace clang {
46
48class ClassTemplateDecl;
49class ClassTemplatePartialSpecializationDecl;
50class Expr;
51class FunctionTemplateDecl;
52class IdentifierInfo;
53class NonTypeTemplateParmDecl;
54class TemplateDecl;
55class TemplateTemplateParmDecl;
56class TemplateTypeParmDecl;
57class ConceptDecl;
58class UnresolvedSetImpl;
59class VarTemplateDecl;
60class VarTemplatePartialSpecializationDecl;
61
62/// Stores a template parameter of any kind.
64 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
66
68
69/// Stores a list of template parameters for a TemplateDecl and its
70/// derived classes.
72 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
73 Expr *> {
74 /// The template argument list of the template parameter list.
75 TemplateArgument *InjectedArgs = nullptr;
76
77 /// The location of the 'template' keyword.
78 SourceLocation TemplateLoc;
79
80 /// The locations of the '<' and '>' angle brackets.
81 SourceLocation LAngleLoc, RAngleLoc;
82
83 /// The number of template parameters in this template
84 /// parameter list.
85 unsigned NumParams : 29;
86
87 /// Whether this template parameter list contains an unexpanded parameter
88 /// pack.
89 LLVM_PREFERRED_TYPE(bool)
90 unsigned ContainsUnexpandedParameterPack : 1;
91
92 /// Whether this template parameter list has a requires clause.
93 LLVM_PREFERRED_TYPE(bool)
94 unsigned HasRequiresClause : 1;
95
96 /// Whether any of the template parameters has constrained-parameter
97 /// constraint-expression.
98 LLVM_PREFERRED_TYPE(bool)
99 unsigned HasConstrainedParameters : 1;
100
101protected:
103 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
104 SourceLocation RAngleLoc, Expr *RequiresClause);
105
106 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
107 return NumParams;
108 }
109
110 size_t numTrailingObjects(OverloadToken<Expr *>) const {
111 return HasRequiresClause ? 1 : 0;
112 }
113
114public:
115 template <size_t N, bool HasRequiresClause>
118
120 SourceLocation TemplateLoc,
121 SourceLocation LAngleLoc,
123 SourceLocation RAngleLoc,
124 Expr *RequiresClause);
125
126 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
127
128 /// Iterates through the template parameters in this list.
129 using iterator = NamedDecl **;
130
131 /// Iterates through the template parameters in this list.
132 using const_iterator = NamedDecl * const *;
133
134 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
135 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
136 iterator end() { return begin() + NumParams; }
137 const_iterator end() const { return begin() + NumParams; }
138
139 unsigned size() const { return NumParams; }
140 bool empty() const { return NumParams == 0; }
141
144 return llvm::ArrayRef(begin(), size());
145 }
146
147 NamedDecl* getParam(unsigned Idx) {
148 assert(Idx < size() && "Template parameter index out-of-range");
149 return begin()[Idx];
150 }
151 const NamedDecl* getParam(unsigned Idx) const {
152 assert(Idx < size() && "Template parameter index out-of-range");
153 return begin()[Idx];
154 }
155
156 /// Returns the minimum number of arguments needed to form a
157 /// template specialization.
158 ///
159 /// This may be fewer than the number of template parameters, if some of
160 /// the parameters have default arguments or if there is a parameter pack.
161 unsigned getMinRequiredArguments() const;
162
163 /// Get the depth of this template parameter list in the set of
164 /// template parameter lists.
165 ///
166 /// The first template parameter list in a declaration will have depth 0,
167 /// the second template parameter list will have depth 1, etc.
168 unsigned getDepth() const;
169
170 /// Determine whether this template parameter list contains an
171 /// unexpanded parameter pack.
173
174 /// Determine whether this template parameter list contains a parameter pack.
175 bool hasParameterPack() const {
176 for (const NamedDecl *P : asArray())
177 if (P->isParameterPack())
178 return true;
179 return false;
180 }
181
182 /// The constraint-expression of the associated requires-clause.
184 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
185 }
186
187 /// The constraint-expression of the associated requires-clause.
188 const Expr *getRequiresClause() const {
189 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
190 }
191
192 /// \brief All associated constraints derived from this template parameter
193 /// list, including the requires clause and any constraints derived from
194 /// constrained-parameters.
195 ///
196 /// The constraints in the resulting list are to be treated as if in a
197 /// conjunction ("and").
199
201
202 /// Get the template argument list of the template parameter list.
204
205 SourceLocation getTemplateLoc() const { return TemplateLoc; }
206 SourceLocation getLAngleLoc() const { return LAngleLoc; }
207 SourceLocation getRAngleLoc() const { return RAngleLoc; }
208
209 SourceRange getSourceRange() const LLVM_READONLY {
210 return SourceRange(TemplateLoc, RAngleLoc);
211 }
212
213 void print(raw_ostream &Out, const ASTContext &Context,
214 bool OmitTemplateKW = false) const;
215 void print(raw_ostream &Out, const ASTContext &Context,
216 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
217
219 const TemplateParameterList *TPL,
220 unsigned Idx);
221};
222
223/// Stores a list of template parameters and the associated
224/// requires-clause (if any) for a TemplateDecl and its derived classes.
225/// Suitable for creating on the stack.
226template <size_t N, bool HasRequiresClause>
228 : public TemplateParameterList::FixedSizeStorageOwner {
229 typename TemplateParameterList::FixedSizeStorage<
230 NamedDecl *, Expr *>::with_counts<
231 N, HasRequiresClause ? 1u : 0u
232 >::type storage;
233
234public:
236 SourceLocation TemplateLoc,
237 SourceLocation LAngleLoc,
239 SourceLocation RAngleLoc,
240 Expr *RequiresClause)
241 : FixedSizeStorageOwner(
242 (assert(N == Params.size()),
243 assert(HasRequiresClause == (RequiresClause != nullptr)),
244 new (static_cast<void *>(&storage)) TemplateParameterList(C,
245 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
246};
247
248/// A template argument list.
250 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
251 /// The number of template arguments in this template
252 /// argument list.
253 unsigned NumArguments;
254
255 // Constructs an instance with an internal Argument list, containing
256 // a copy of the Args array. (Called by CreateCopy)
258
259public:
261
264
265 /// Create a new template argument list that copies the given set of
266 /// template arguments.
269
270 /// Retrieve the template argument at a given index.
271 const TemplateArgument &get(unsigned Idx) const {
272 assert(Idx < NumArguments && "Invalid template argument index");
273 return data()[Idx];
274 }
275
276 /// Retrieve the template argument at a given index.
277 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
278
279 /// Produce this as an array ref.
281 return llvm::ArrayRef(data(), size());
282 }
283
284 /// Retrieve the number of template arguments in this
285 /// template argument list.
286 unsigned size() const { return NumArguments; }
287
288 /// Retrieve a pointer to the template argument list.
289 const TemplateArgument *data() const {
290 return getTrailingObjects<TemplateArgument>();
291 }
292};
293
294void *allocateDefaultArgStorageChain(const ASTContext &C);
295
296/// Storage for a default argument. This is conceptually either empty, or an
297/// argument value, or a pointer to a previous declaration that had a default
298/// argument.
299///
300/// However, this is complicated by modules: while we require all the default
301/// arguments for a template to be equivalent, there may be more than one, and
302/// we need to track all the originating parameters to determine if the default
303/// argument is visible.
304template<typename ParmDecl, typename ArgType>
306 /// Storage for both the value *and* another parameter from which we inherit
307 /// the default argument. This is used when multiple default arguments for a
308 /// parameter are merged together from different modules.
309 struct Chain {
310 ParmDecl *PrevDeclWithDefaultArg;
311 ArgType Value;
312 };
313 static_assert(sizeof(Chain) == sizeof(void *) * 2,
314 "non-pointer argument type?");
315
316 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
317
318 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
319 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
320 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
321 Parm = Prev;
322 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
323 "should only be one level of indirection");
324 return Parm;
325 }
326
327public:
328 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
329
330 /// Determine whether there is a default argument for this parameter.
331 bool isSet() const { return !ValueOrInherited.isNull(); }
332
333 /// Determine whether the default argument for this parameter was inherited
334 /// from a previous declaration of the same entity.
335 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
336
337 /// Get the default argument's value. This does not consider whether the
338 /// default argument is visible.
339 ArgType get() const {
340 const DefaultArgStorage *Storage = this;
341 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
342 Storage = &Prev->getDefaultArgStorage();
343 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
344 return C->Value;
345 return cast<ArgType>(Storage->ValueOrInherited);
346 }
347
348 /// Get the parameter from which we inherit the default argument, if any.
349 /// This is the parameter on which the default argument was actually written.
350 const ParmDecl *getInheritedFrom() const {
351 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
352 return D;
353 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
354 return C->PrevDeclWithDefaultArg;
355 return nullptr;
356 }
357
358 /// Set the default argument.
359 void set(ArgType Arg) {
360 assert(!isSet() && "default argument already set");
361 ValueOrInherited = Arg;
362 }
363
364 /// Set that the default argument was inherited from another parameter.
365 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
366 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
367 if (!isSet())
368 ValueOrInherited = InheritedFrom;
369 else if ([[maybe_unused]] auto *D =
370 dyn_cast<ParmDecl *>(ValueOrInherited)) {
371 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
372 ValueOrInherited =
373 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
374 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
375 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
376 InheritedFrom));
377 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
378 } else
379 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
380 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
381 }
382
383 /// Remove the default argument, even if it was inherited.
384 void clear() {
385 ValueOrInherited = ArgType();
386 }
387};
388
389//===----------------------------------------------------------------------===//
390// Kinds of Templates
391//===----------------------------------------------------------------------===//
392
393/// \brief The base class of all kinds of template declarations (e.g.,
394/// class, function, etc.).
395///
396/// The TemplateDecl class stores the list of template parameters and a
397/// reference to the templated scoped declaration: the underlying AST node.
398class TemplateDecl : public NamedDecl {
399 void anchor() override;
400
401protected:
402 // Construct a template decl with name, parameters, and templated element.
405
406 // Construct a template decl with the given name and parameters.
407 // Used when there is no templated element (e.g., for tt-params).
409 TemplateParameterList *Params)
410 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
411
412public:
413 friend class ASTDeclReader;
414 friend class ASTDeclWriter;
415
416 /// Get the list of template parameters
418 return TemplateParams;
419 }
420
421 /// \brief Get the total constraint-expression associated with this template,
422 /// including constraint-expressions derived from the requires-clause,
423 /// trailing requires-clause (for functions and methods) and constrained
424 /// 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(),
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.
469 : public llvm::FoldingSetNode,
470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
471 MemberSpecializationInfo *> {
472 /// The function template specialization that this structure describes and a
473 /// flag indicating if the function is a member specialization.
474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
475
476 /// The function template from which this function template
477 /// specialization was generated.
478 ///
479 /// The two bits contain the top 4 values of TemplateSpecializationKind.
480 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
481
482public:
483 /// The template arguments used to produce the function template
484 /// specialization from the function template.
486
487 /// The template arguments as written in the sources, if provided.
488 /// FIXME: Normally null; tail-allocate this.
490
491 /// The point at which this function template specialization was
492 /// first instantiated.
494
495private:
497 FunctionDecl *FD, FunctionTemplateDecl *Template,
499 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
501 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
502 TemplateArguments(TemplateArgs),
503 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
505 if (MSInfo)
506 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
507 }
508
509 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
510 return Function.getInt();
511 }
512
513public:
515
519 const TemplateArgumentListInfo *TemplateArgsAsWritten,
521
522 /// Retrieve the declaration of the function template specialization.
523 FunctionDecl *getFunction() const { return Function.getPointer(); }
524
525 /// Retrieve the template from which this function was specialized.
526 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
527
528 /// Determine what kind of template specialization this is.
530 return (TemplateSpecializationKind)(Template.getInt() + 1);
531 }
532
535 }
536
537 /// True if this declaration is an explicit specialization,
538 /// explicit instantiation declaration, or explicit instantiation
539 /// definition.
543 }
544
545 /// Set the template specialization kind.
547 assert(TSK != TSK_Undeclared &&
548 "Cannot encode TSK_Undeclared for a function template specialization");
549 Template.setInt(TSK - 1);
550 }
551
552 /// Retrieve the first point of instantiation of this function
553 /// template specialization.
554 ///
555 /// The point of instantiation may be an invalid source location if this
556 /// function has yet to be instantiated.
559 }
560
561 /// Set the (first) point of instantiation of this function template
562 /// specialization.
565 }
566
567 /// Get the specialization info if this function template specialization is
568 /// also a member specialization:
569 ///
570 /// \code
571 /// template<typename> struct A {
572 /// template<typename> void f();
573 /// template<> void f<int>();
574 /// };
575 /// \endcode
576 ///
577 /// Here, A<int>::f<int> is a function template specialization that is
578 /// an explicit specialization of A<int>::f, but it's also a member
579 /// specialization (an implicit instantiation in this case) of A::f<int>.
580 /// Further:
581 ///
582 /// \code
583 /// template<> template<> void A<int>::f<int>() {}
584 /// \endcode
585 ///
586 /// ... declares a function template specialization that is an explicit
587 /// specialization of A<int>::f, and is also an explicit member
588 /// specialization of A::f<int>.
589 ///
590 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
591 /// need not be the same as that returned by getTemplateSpecializationKind(),
592 /// and represents the relationship between the function and the class-scope
593 /// explicit specialization in the original templated class -- whereas our
594 /// TemplateSpecializationKind represents the relationship between the
595 /// function and the function template, and should always be
596 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
598 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
599 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
600 : nullptr;
601 }
602
603 void Profile(llvm::FoldingSetNodeID &ID) {
604 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
605 }
606
607 static void
608 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
609 const ASTContext &Context) {
610 ID.AddInteger(TemplateArgs.size());
611 for (const TemplateArgument &TemplateArg : TemplateArgs)
612 TemplateArg.Profile(ID, Context);
613 }
614};
615
616/// Provides information a specialization of a member of a class
617/// template, which may be a member function, static data member,
618/// member class or member enumeration.
620 // The member declaration from which this member was instantiated, and the
621 // manner in which the instantiation occurred (in the lower two bits).
622 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
623
624 // The point at which this member was first instantiated.
625 SourceLocation PointOfInstantiation;
626
627public:
628 explicit
631 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
632 assert(TSK != TSK_Undeclared &&
633 "Cannot encode undeclared template specializations for members");
634 }
635
636 /// Retrieve the member declaration from which this member was
637 /// instantiated.
638 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
639
640 /// Determine what kind of template specialization this is.
642 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
643 }
644
647 }
648
649 /// Set the template specialization kind.
651 assert(TSK != TSK_Undeclared &&
652 "Cannot encode undeclared template specializations for members");
653 MemberAndTSK.setInt(TSK - 1);
654 }
655
656 /// Retrieve the first point of instantiation of this member.
657 /// If the point of instantiation is an invalid location, then this member
658 /// has not yet been instantiated.
660 return PointOfInstantiation;
661 }
662
663 /// Set the first point of instantiation.
665 PointOfInstantiation = POI;
666 }
667};
668
669/// Provides information about a dependent function-template
670/// specialization declaration.
671///
672/// This is used for function templates explicit specializations declared
673/// within class templates:
674///
675/// \code
676/// template<typename> struct A {
677/// template<typename> void f();
678/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
679/// };
680/// \endcode
681///
682/// As well as dependent friend declarations naming function template
683/// specializations declared within class templates:
684///
685/// \code
686/// template <class T> void foo(T);
687/// template <class T> class A {
688/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
689/// };
690/// \endcode
692 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
693 FunctionTemplateDecl *> {
694 friend TrailingObjects;
695
696 /// The number of candidates for the primary template.
697 unsigned NumCandidates;
698
700 const UnresolvedSetImpl &Candidates,
701 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
702
703public:
704 /// The template arguments as written in the sources, if provided.
706
708 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
709 const TemplateArgumentListInfo *TemplateArgs);
710
711 /// Returns the candidates for the primary function template.
713 return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
714 }
715};
716
717/// Declaration of a redeclarable template.
719 public Redeclarable<RedeclarableTemplateDecl>
720{
722
723 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
724 return getNextRedeclaration();
725 }
726
727 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
728 return getPreviousDecl();
729 }
730
731 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
732 return getMostRecentDecl();
733 }
734
735 void anchor() override;
736
737protected:
738 template <typename EntryType> struct SpecEntryTraits {
739 using DeclType = EntryType;
740
741 static DeclType *getDecl(EntryType *D) {
742 return D;
743 }
744
746 return D->getTemplateArgs().asArray();
747 }
748 };
749
750 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
751 typename DeclType = typename SETraits::DeclType>
753 : llvm::iterator_adaptor_base<
754 SpecIterator<EntryType, SETraits, DeclType>,
755 typename llvm::FoldingSetVector<EntryType>::iterator,
756 typename std::iterator_traits<typename llvm::FoldingSetVector<
757 EntryType>::iterator>::iterator_category,
758 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
759 SpecIterator() = default;
760 explicit SpecIterator(
761 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
762 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
763
764 DeclType *operator*() const {
765 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
766 }
767
768 DeclType *operator->() const { return **this; }
769 };
770
771 template <typename EntryType>
772 static SpecIterator<EntryType>
773 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
774 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
775 }
776
777 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
778
780 TemplateParameterList *TPL = nullptr) const;
781
782 template <class EntryType, typename ...ProfileArguments>
784 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
785 void *&InsertPos, ProfileArguments &&...ProfileArgs);
786
787 template <class EntryType, typename... ProfileArguments>
789 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
790 void *&InsertPos,
791 ProfileArguments &&...ProfileArgs);
792
793 template <class Derived, class EntryType>
794 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
795 EntryType *Entry, void *InsertPos);
796
797 struct CommonBase {
799
800 /// The template from which this was most
801 /// directly instantiated (or null).
802 ///
803 /// The boolean value indicates whether this template
804 /// was explicitly specialized.
805 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
807 };
808
809 /// Pointer to the common data shared by all declarations of this
810 /// template.
811 mutable CommonBase *Common = nullptr;
812
813 /// Retrieves the "common" pointer shared by all (re-)declarations of
814 /// the same template. Calling this routine may implicitly allocate memory
815 /// for the common pointer.
816 CommonBase *getCommonPtr() const;
817
818 virtual CommonBase *newCommon(ASTContext &C) const = 0;
819
820 // Construct a template decl with name, parameters, and templated element.
824 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
825
826public:
827 friend class ASTDeclReader;
828 friend class ASTDeclWriter;
829 friend class ASTReader;
830 template <class decl_type> friend class RedeclarableTemplate;
831
832 /// Retrieves the canonical declaration of this template.
834 return getFirstDecl();
835 }
837 return getFirstDecl();
838 }
839
840 /// Determines whether this template was a specialization of a
841 /// member template.
842 ///
843 /// In the following example, the function template \c X<int>::f and the
844 /// member template \c X<int>::Inner are member specializations.
845 ///
846 /// \code
847 /// template<typename T>
848 /// struct X {
849 /// template<typename U> void f(T, U);
850 /// template<typename U> struct Inner;
851 /// };
852 ///
853 /// template<> template<typename T>
854 /// void X<int>::f(int, T);
855 /// template<> template<typename T>
856 /// struct X<int>::Inner { /* ... */ };
857 /// \endcode
859 return getCommonPtr()->InstantiatedFromMember.getInt();
860 }
861
862 /// Note that this member template is a specialization.
864 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
865 "Only member templates can be member template specializations");
866 getCommonPtr()->InstantiatedFromMember.setInt(true);
867 }
868
869 /// Retrieve the member template from which this template was
870 /// instantiated, or nullptr if this template was not instantiated from a
871 /// member template.
872 ///
873 /// A template is instantiated from a member template when the member
874 /// template itself is part of a class template (or member thereof). For
875 /// example, given
876 ///
877 /// \code
878 /// template<typename T>
879 /// struct X {
880 /// template<typename U> void f(T, U);
881 /// };
882 ///
883 /// void test(X<int> x) {
884 /// x.f(1, 'a');
885 /// };
886 /// \endcode
887 ///
888 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
889 /// template
890 ///
891 /// \code
892 /// template<typename U> void X<int>::f(int, U);
893 /// \endcode
894 ///
895 /// which was itself created during the instantiation of \c X<int>. Calling
896 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
897 /// retrieve the FunctionTemplateDecl for the original template \c f within
898 /// the class template \c X<T>, i.e.,
899 ///
900 /// \code
901 /// template<typename T>
902 /// template<typename U>
903 /// void X<T>::f(T, U);
904 /// \endcode
906 return getCommonPtr()->InstantiatedFromMember.getPointer();
907 }
908
910 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
911 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
912 }
913
914 /// Retrieve the "injected" template arguments that correspond to the
915 /// template parameters of this template.
916 ///
917 /// Although the C++ standard has no notion of the "injected" template
918 /// arguments for a template, the notion is convenient when
919 /// we need to perform substitutions inside the definition of a template.
921 getInjectedTemplateArgs(const ASTContext &Context) const {
923 }
924
926 using redecl_iterator = redeclarable_base::redecl_iterator;
927
934
935 // Implement isa/cast/dyncast/etc.
936 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
937
938 static bool classofKind(Kind K) {
939 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
940 }
941};
942
943template <> struct RedeclarableTemplateDecl::
944SpecEntryTraits<FunctionTemplateSpecializationInfo> {
946
948 return I->getFunction();
949 }
950
953 return I->TemplateArguments->asArray();
954 }
955};
956
957/// Declaration of a template function.
959protected:
960 friend class FunctionDecl;
961
962 /// Data that is common to all of the declarations of a given
963 /// function template.
965 /// The function template specializations for this function
966 /// template, including explicit specializations and instantiations.
967 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
968
969 Common() = default;
970 };
971
975 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
976 Decl) {}
977
978 CommonBase *newCommon(ASTContext &C) const override;
979
981 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
982 }
983
984 /// Retrieve the set of function template specializations of this
985 /// function template.
986 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
987 getSpecializations() const;
988
989 /// Add a specialization of this function template.
990 ///
991 /// \param InsertPos Insert position in the FoldingSetVector, must have been
992 /// retrieved by an earlier call to findSpecialization().
994 void *InsertPos);
995
996public:
997 friend class ASTDeclReader;
998 friend class ASTDeclWriter;
999
1000 /// Load any lazily-loaded specializations from the external source.
1001 void LoadLazySpecializations() const;
1002
1003 /// Get the underlying function declaration of the template.
1005 return static_cast<FunctionDecl *>(TemplatedDecl);
1006 }
1007
1008 /// Returns whether this template declaration defines the primary
1009 /// pattern.
1012 }
1013
1017 }
1021 }
1022
1023 /// Return the specialization with the provided arguments if it exists,
1024 /// otherwise return the insertion point.
1026 void *&InsertPos);
1027
1029 return cast<FunctionTemplateDecl>(
1031 }
1033 return cast<FunctionTemplateDecl>(
1035 }
1036
1037 /// Retrieve the previous declaration of this function template, or
1038 /// nullptr if no such declaration exists.
1040 return cast_or_null<FunctionTemplateDecl>(
1041 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1042 }
1044 return cast_or_null<FunctionTemplateDecl>(
1045 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1046 }
1047
1049 return cast<FunctionTemplateDecl>(
1050 static_cast<RedeclarableTemplateDecl *>(this)
1051 ->getMostRecentDecl());
1052 }
1054 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1055 }
1056
1058 return cast_or_null<FunctionTemplateDecl>(
1060 }
1061
1063 using spec_range = llvm::iterator_range<spec_iterator>;
1064
1066 return spec_range(spec_begin(), spec_end());
1067 }
1068
1070 return makeSpecIterator(getSpecializations(), false);
1071 }
1072
1074 return makeSpecIterator(getSpecializations(), true);
1075 }
1076
1077 /// Return whether this function template is an abbreviated function template,
1078 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1079 bool isAbbreviated() const {
1080 // Since the invented template parameters generated from 'auto' parameters
1081 // are either appended to the end of the explicit template parameter list or
1082 // form a new template parameter list, we can simply observe the last
1083 // parameter to determine if such a thing happened.
1085 return TPL->getParam(TPL->size() - 1)->isImplicit();
1086 }
1087
1088 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1090
1091 /// Create a function template node.
1094 DeclarationName Name,
1095 TemplateParameterList *Params,
1096 NamedDecl *Decl);
1097
1098 /// Create an empty function template node.
1101
1102 // Implement isa/cast/dyncast support
1103 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1104 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1105};
1106
1107//===----------------------------------------------------------------------===//
1108// Kinds of Template Parameters
1109//===----------------------------------------------------------------------===//
1110
1111/// Defines the position of a template parameter within a template
1112/// parameter list.
1113///
1114/// Because template parameter can be listed
1115/// sequentially for out-of-line template members, each template parameter is
1116/// given a Depth - the nesting of template parameter scopes - and a Position -
1117/// the occurrence within the parameter list.
1118/// This class is inheritedly privately by different kinds of template
1119/// parameters and is not part of the Decl hierarchy. Just a facility.
1121protected:
1122 enum { DepthWidth = 20, PositionWidth = 12 };
1123 unsigned Depth : DepthWidth;
1125
1126 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1127 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1128
1129 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1130 // The input may fill maximum values to show that it is invalid.
1131 // Add one here to convert it to zero.
1132 assert((D + 1) <= MaxDepth &&
1133 "The depth of template parmeter position is more than 2^20!");
1134 assert((P + 1) <= MaxPosition &&
1135 "The position of template parmeter position is more than 2^12!");
1136 }
1137
1138public:
1140
1141 /// Get the nesting depth of the template parameter.
1142 unsigned getDepth() const { return Depth; }
1143 void setDepth(unsigned D) {
1144 assert((D + 1) <= MaxDepth &&
1145 "The depth of template parmeter position is more than 2^20!");
1146 Depth = D;
1147 }
1148
1149 /// Get the position of the template parameter within its parameter list.
1150 unsigned getPosition() const { return Position; }
1151 void setPosition(unsigned P) {
1152 assert((P + 1) <= MaxPosition &&
1153 "The position of template parmeter position is more than 2^12!");
1154 Position = P;
1155 }
1156
1157 /// Get the index of the template parameter within its parameter list.
1158 unsigned getIndex() const { return Position; }
1159};
1160
1161/// Declaration of a template type parameter.
1162///
1163/// For example, "T" in
1164/// \code
1165/// template<typename T> class vector;
1166/// \endcode
1167class TemplateTypeParmDecl final : public TypeDecl,
1168 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1169 /// Sema creates these on the stack during auto type deduction.
1170 friend class Sema;
1171 friend TrailingObjects;
1172 friend class ASTDeclReader;
1173
1174 /// Whether this template type parameter was declaration with
1175 /// the 'typename' keyword.
1176 ///
1177 /// If false, it was declared with the 'class' keyword.
1178 bool Typename : 1;
1179
1180 /// Whether this template type parameter has a type-constraint construct.
1181 bool HasTypeConstraint : 1;
1182
1183 /// Whether the type constraint has been initialized. This can be false if the
1184 /// constraint was not initialized yet or if there was an error forming the
1185 /// type constraint.
1186 bool TypeConstraintInitialized : 1;
1187
1188 /// Whether this type template parameter is an "expanded"
1189 /// parameter pack, meaning that its type is a pack expansion and we
1190 /// already know the set of types that expansion expands to.
1191 bool ExpandedParameterPack : 1;
1192
1193 /// The number of type parameters in an expanded parameter pack.
1194 unsigned NumExpanded = 0;
1195
1196 /// The default template argument, if any.
1197 using DefArgStorage =
1199 DefArgStorage DefaultArgument;
1200
1202 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1203 bool HasTypeConstraint,
1204 std::optional<unsigned> NumExpanded)
1205 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1206 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1207 ExpandedParameterPack(NumExpanded),
1208 NumExpanded(NumExpanded.value_or(0)) {}
1209
1210public:
1211 static TemplateTypeParmDecl *
1212 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1213 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1214 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1215 std::optional<unsigned> NumExpanded = std::nullopt);
1220 bool HasTypeConstraint);
1221
1222 /// Whether this template type parameter was declared with
1223 /// the 'typename' keyword.
1224 ///
1225 /// If not, it was either declared with the 'class' keyword or with a
1226 /// type-constraint (see hasTypeConstraint()).
1228 return Typename && !HasTypeConstraint;
1229 }
1230
1231 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1232
1233 /// Determine whether this template parameter has a default
1234 /// argument.
1235 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1236
1237 /// Retrieve the default argument, if any.
1239 static const TemplateArgumentLoc NoneLoc;
1240 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1241 }
1242
1243 /// Retrieves the location of the default argument declaration.
1245
1246 /// Determines whether the default argument was inherited
1247 /// from a previous declaration of this template.
1249 return DefaultArgument.isInherited();
1250 }
1251
1252 /// Set the default argument for this template parameter.
1253 void setDefaultArgument(const ASTContext &C,
1254 const TemplateArgumentLoc &DefArg);
1255
1256 /// Set that this default argument was inherited from another
1257 /// parameter.
1259 TemplateTypeParmDecl *Prev) {
1260 DefaultArgument.setInherited(C, Prev);
1261 }
1262
1263 /// Removes the default argument of this template parameter.
1265 DefaultArgument.clear();
1266 }
1267
1268 /// Set whether this template type parameter was declared with
1269 /// the 'typename' or 'class' keyword.
1270 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1271
1272 /// Retrieve the depth of the template parameter.
1273 unsigned getDepth() const;
1274
1275 /// Retrieve the index of the template parameter.
1276 unsigned getIndex() const;
1277
1278 /// Returns whether this is a parameter pack.
1279 bool isParameterPack() const;
1280
1281 /// Whether this parameter pack is a pack expansion.
1282 ///
1283 /// A template type template parameter pack can be a pack expansion if its
1284 /// type-constraint contains an unexpanded parameter pack.
1285 bool isPackExpansion() const {
1286 if (!isParameterPack())
1287 return false;
1288 if (const TypeConstraint *TC = getTypeConstraint())
1289 if (TC->hasExplicitTemplateArgs())
1290 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1291 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1292 return true;
1293 return false;
1294 }
1295
1296 /// Whether this parameter is a template type parameter pack that has a known
1297 /// list of different type-constraints at different positions.
1298 ///
1299 /// A parameter pack is an expanded parameter pack when the original
1300 /// parameter pack's type-constraint was itself a pack expansion, and that
1301 /// expansion has already been expanded. For example, given:
1302 ///
1303 /// \code
1304 /// template<typename ...Types>
1305 /// struct X {
1306 /// template<convertible_to<Types> ...Convertibles>
1307 /// struct Y { /* ... */ };
1308 /// };
1309 /// \endcode
1310 ///
1311 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1312 /// its type-constraint. When \c Types is supplied with template arguments by
1313 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1314 /// expanded parameter pack. For example, instantiating
1315 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1316 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1317 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1318
1319 /// Retrieves the number of parameters in an expanded parameter pack.
1320 unsigned getNumExpansionParameters() const {
1321 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1322 return NumExpanded;
1323 }
1324
1325 /// Returns the type constraint associated with this template parameter (if
1326 /// any).
1328 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1329 nullptr;
1330 }
1331
1333 Expr *ImmediatelyDeclaredConstraint);
1334
1335 /// Determine whether this template parameter has a type-constraint.
1336 bool hasTypeConstraint() const {
1337 return HasTypeConstraint;
1338 }
1339
1340 /// \brief Get the associated-constraints of this template parameter.
1341 /// This will either be the immediately-introduced constraint or empty.
1342 ///
1343 /// Use this instead of getTypeConstraint for concepts APIs that
1344 /// accept an ArrayRef of constraint expressions.
1346 if (HasTypeConstraint)
1347 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1348 }
1349
1350 SourceRange getSourceRange() const override LLVM_READONLY;
1351
1352 // Implement isa/cast/dyncast/etc.
1353 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1354 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1355};
1356
1357/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1358/// e.g., "Size" in
1359/// @code
1360/// template<int Size> class array { };
1361/// @endcode
1363 : public DeclaratorDecl,
1364 protected TemplateParmPosition,
1365 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1366 std::pair<QualType, TypeSourceInfo *>,
1367 Expr *> {
1368 friend class ASTDeclReader;
1369 friend TrailingObjects;
1370
1371 /// The default template argument, if any, and whether or not
1372 /// it was inherited.
1373 using DefArgStorage =
1375 DefArgStorage DefaultArgument;
1376
1377 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1378 // down here to save memory.
1379
1380 /// Whether this non-type template parameter is a parameter pack.
1381 bool ParameterPack;
1382
1383 /// Whether this non-type template parameter is an "expanded"
1384 /// parameter pack, meaning that its type is a pack expansion and we
1385 /// already know the set of types that expansion expands to.
1386 bool ExpandedParameterPack = false;
1387
1388 /// The number of types in an expanded parameter pack.
1389 unsigned NumExpandedTypes = 0;
1390
1391 size_t numTrailingObjects(
1392 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1393 return NumExpandedTypes;
1394 }
1395
1397 SourceLocation IdLoc, unsigned D, unsigned P,
1398 const IdentifierInfo *Id, QualType T,
1399 bool ParameterPack, TypeSourceInfo *TInfo)
1400 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1401 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1402
1403 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1404 SourceLocation IdLoc, unsigned D, unsigned P,
1405 const IdentifierInfo *Id, QualType T,
1406 TypeSourceInfo *TInfo,
1407 ArrayRef<QualType> ExpandedTypes,
1408 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1409
1410public:
1411 static NonTypeTemplateParmDecl *
1412 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1413 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1414 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1415
1416 static NonTypeTemplateParmDecl *
1417 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1418 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1419 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1420 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1421
1422 static NonTypeTemplateParmDecl *
1423 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1424 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1425 GlobalDeclID ID,
1426 unsigned NumExpandedTypes,
1427 bool HasTypeConstraint);
1428
1434
1435 SourceRange getSourceRange() const override LLVM_READONLY;
1436
1437 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1438
1439 /// Determine whether this template parameter has a default
1440 /// argument.
1441 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1442
1443 /// Retrieve the default argument, if any.
1445 static const TemplateArgumentLoc NoneLoc;
1446 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1447 }
1448
1449 /// Retrieve the location of the default argument, if any.
1451
1452 /// Determines whether the default argument was inherited
1453 /// from a previous declaration of this template.
1455 return DefaultArgument.isInherited();
1456 }
1457
1458 /// Set the default argument for this template parameter, and
1459 /// whether that default argument was inherited from another
1460 /// declaration.
1461 void setDefaultArgument(const ASTContext &C,
1462 const TemplateArgumentLoc &DefArg);
1465 DefaultArgument.setInherited(C, Parm);
1466 }
1467
1468 /// Removes the default argument of this template parameter.
1469 void removeDefaultArgument() { DefaultArgument.clear(); }
1470
1471 /// Whether this parameter is a non-type template parameter pack.
1472 ///
1473 /// If the parameter is a parameter pack, the type may be a
1474 /// \c PackExpansionType. In the following example, the \c Dims parameter
1475 /// is a parameter pack (whose type is 'unsigned').
1476 ///
1477 /// \code
1478 /// template<typename T, unsigned ...Dims> struct multi_array;
1479 /// \endcode
1480 bool isParameterPack() const { return ParameterPack; }
1481
1482 /// Whether this parameter pack is a pack expansion.
1483 ///
1484 /// A non-type template parameter pack is a pack expansion if its type
1485 /// contains an unexpanded parameter pack. In this case, we will have
1486 /// built a PackExpansionType wrapping the type.
1487 bool isPackExpansion() const {
1488 return ParameterPack && getType()->getAs<PackExpansionType>();
1489 }
1490
1491 /// Whether this parameter is a non-type template parameter pack
1492 /// that has a known list of different types at different positions.
1493 ///
1494 /// A parameter pack is an expanded parameter pack when the original
1495 /// parameter pack's type was itself a pack expansion, and that expansion
1496 /// has already been expanded. For example, given:
1497 ///
1498 /// \code
1499 /// template<typename ...Types>
1500 /// struct X {
1501 /// template<Types ...Values>
1502 /// struct Y { /* ... */ };
1503 /// };
1504 /// \endcode
1505 ///
1506 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1507 /// which expands \c Types. When \c Types is supplied with template arguments
1508 /// by instantiating \c X, the instantiation of \c Values becomes an
1509 /// expanded parameter pack. For example, instantiating
1510 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1511 /// pack with expansion types \c int and \c unsigned int.
1512 ///
1513 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1514 /// return the expansion types.
1515 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1516
1517 /// Retrieves the number of expansion types in an expanded parameter
1518 /// pack.
1519 unsigned getNumExpansionTypes() const {
1520 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1521 return NumExpandedTypes;
1522 }
1523
1524 /// Retrieve a particular expansion type within an expanded parameter
1525 /// pack.
1526 QualType getExpansionType(unsigned I) const {
1527 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1528 auto TypesAndInfos =
1529 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1530 return TypesAndInfos[I].first;
1531 }
1532
1533 /// Retrieve a particular expansion type source info within an
1534 /// expanded parameter pack.
1536 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1537 auto TypesAndInfos =
1538 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1539 return TypesAndInfos[I].second;
1540 }
1541
1542 /// Return the constraint introduced by the placeholder type of this non-type
1543 /// template parameter (if any).
1545 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1546 nullptr;
1547 }
1548
1550 *getTrailingObjects<Expr *>() = E;
1551 }
1552
1553 /// Determine whether this non-type template parameter's type has a
1554 /// placeholder with a type-constraint.
1556 auto *AT = getType()->getContainedAutoType();
1557 return AT && AT->isConstrained();
1558 }
1559
1560 /// \brief Get the associated-constraints of this template parameter.
1561 /// This will either be a vector of size 1 containing the immediately-declared
1562 /// constraint introduced by the placeholder type, or an empty vector.
1563 ///
1564 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1565 /// concepts APIs that accept an ArrayRef of constraint expressions.
1568 AC.push_back(E);
1569 }
1570
1571 // Implement isa/cast/dyncast/etc.
1572 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1573 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1574};
1575
1576/// TemplateTemplateParmDecl - Declares a template template parameter,
1577/// e.g., "T" in
1578/// @code
1579/// template <template <typename> class T> class container { };
1580/// @endcode
1581/// A template template parameter is a TemplateDecl because it defines the
1582/// name of a template and the template parameters allowable for substitution.
1584 : public TemplateDecl,
1585 protected TemplateParmPosition,
1586 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1587 TemplateParameterList *> {
1588 /// The default template argument, if any.
1589 using DefArgStorage =
1591 DefArgStorage DefaultArgument;
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
1614 unsigned P, bool ParameterPack, IdentifierInfo *Id,
1615 bool Typename, TemplateParameterList *Params)
1616 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1618 ParameterPack(ParameterPack), ExpandedParameterPack(false) {}
1619
1621 unsigned P, IdentifierInfo *Id, bool Typename,
1622 TemplateParameterList *Params,
1624
1625 void anchor() override;
1626
1627public:
1628 friend class ASTDeclReader;
1629 friend class ASTDeclWriter;
1631
1633 SourceLocation L, unsigned D,
1634 unsigned P, bool ParameterPack,
1635 IdentifierInfo *Id, bool Typename,
1636 TemplateParameterList *Params);
1638 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
1639 unsigned P, IdentifierInfo *Id, bool Typename,
1640 TemplateParameterList *Params,
1642
1646 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1647
1653
1654 /// Whether this template template parameter was declared with
1655 /// the 'typename' keyword.
1656 bool wasDeclaredWithTypename() const { return Typename; }
1657
1658 /// Set whether this template template parameter was declared with
1659 /// the 'typename' or 'class' keyword.
1660 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1661
1662 /// Whether this template template parameter is a template
1663 /// parameter pack.
1664 ///
1665 /// \code
1666 /// template<template <class T> ...MetaFunctions> struct Apply;
1667 /// \endcode
1668 bool isParameterPack() const { return ParameterPack; }
1669
1670 /// Whether this parameter pack is a pack expansion.
1671 ///
1672 /// A template template parameter pack is a pack expansion if its template
1673 /// parameter list contains an unexpanded parameter pack.
1674 bool isPackExpansion() const {
1675 return ParameterPack &&
1677 }
1678
1679 /// Whether this parameter is a template template parameter pack that
1680 /// has a known list of different template parameter lists at different
1681 /// positions.
1682 ///
1683 /// A parameter pack is an expanded parameter pack when the original parameter
1684 /// pack's template parameter list was itself a pack expansion, and that
1685 /// expansion has already been expanded. For exampe, given:
1686 ///
1687 /// \code
1688 /// template<typename...Types> struct Outer {
1689 /// template<template<Types> class...Templates> struct Inner;
1690 /// };
1691 /// \endcode
1692 ///
1693 /// The parameter pack \c Templates is a pack expansion, which expands the
1694 /// pack \c Types. When \c Types is supplied with template arguments by
1695 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1696 /// parameter pack.
1697 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1698
1699 /// Retrieves the number of expansion template parameters in
1700 /// an expanded parameter pack.
1702 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1703 return NumExpandedParams;
1704 }
1705
1706 /// Retrieve a particular expansion type within an expanded parameter
1707 /// pack.
1709 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1710 return getTrailingObjects<TemplateParameterList *>()[I];
1711 }
1712
1713 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1714
1715 /// Determine whether this template parameter has a default
1716 /// argument.
1717 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1718
1719 /// Retrieve the default argument, if any.
1721 static const TemplateArgumentLoc NoneLoc;
1722 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1723 }
1724
1725 /// Retrieve the location of the default argument, if any.
1727
1728 /// Determines whether the default argument was inherited
1729 /// from a previous declaration of this template.
1731 return DefaultArgument.isInherited();
1732 }
1733
1734 /// Set the default argument for this template parameter, and
1735 /// whether that default argument was inherited from another
1736 /// declaration.
1737 void setDefaultArgument(const ASTContext &C,
1738 const TemplateArgumentLoc &DefArg);
1741 DefaultArgument.setInherited(C, Prev);
1742 }
1743
1744 /// Removes the default argument of this template parameter.
1745 void removeDefaultArgument() { DefaultArgument.clear(); }
1746
1747 SourceRange getSourceRange() const override LLVM_READONLY {
1751 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1752 }
1753
1754 // Implement isa/cast/dyncast/etc.
1755 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1756 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1757};
1758
1759/// Represents the builtin template declaration which is used to
1760/// implement __make_integer_seq and other builtin templates. It serves
1761/// no real purpose beyond existing as a place to hold template parameters.
1764
1767
1768 void anchor() override;
1769
1770public:
1771 // Implement isa/cast/dyncast support
1772 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1773 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1774
1776 DeclarationName Name,
1777 BuiltinTemplateKind BTK) {
1778 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1779 }
1780
1781 SourceRange getSourceRange() const override LLVM_READONLY {
1782 return {};
1783 }
1784
1786};
1787
1788/// Provides information about an explicit instantiation of a variable or class
1789/// template.
1791 /// The template arguments as written..
1793
1794 /// The location of the extern keyword.
1796
1797 /// The location of the template keyword.
1799
1801};
1802
1804 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1806
1807/// Represents a class template specialization, which refers to
1808/// a class template with a given set of template arguments.
1809///
1810/// Class template specializations represent both explicit
1811/// specialization of class templates, as in the example below, and
1812/// implicit instantiations of class templates.
1813///
1814/// \code
1815/// template<typename T> class array;
1816///
1817/// template<>
1818/// class array<bool> { }; // class template specialization array<bool>
1819/// \endcode
1821 public llvm::FoldingSetNode {
1822 /// Structure that stores information about a class template
1823 /// specialization that was instantiated from a class template partial
1824 /// specialization.
1825 struct SpecializedPartialSpecialization {
1826 /// The class template partial specialization from which this
1827 /// class template specialization was instantiated.
1828 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1829
1830 /// The template argument list deduced for the class template
1831 /// partial specialization itself.
1832 const TemplateArgumentList *TemplateArgs;
1833 };
1834
1835 /// The template that this specialization specializes
1836 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1837 SpecializedTemplate;
1838
1839 /// Further info for explicit template specialization/instantiation.
1840 /// Does not apply to implicit specializations.
1841 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1842
1843 /// The template arguments used to describe this specialization.
1844 const TemplateArgumentList *TemplateArgs;
1845
1846 /// The point where this template was instantiated (if any)
1847 SourceLocation PointOfInstantiation;
1848
1849 /// The kind of specialization this declaration refers to.
1850 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1851 unsigned SpecializationKind : 3;
1852
1853protected:
1855 DeclContext *DC, SourceLocation StartLoc,
1856 SourceLocation IdLoc,
1857 ClassTemplateDecl *SpecializedTemplate,
1860
1862
1863public:
1864 friend class ASTDeclReader;
1865 friend class ASTDeclWriter;
1866
1868 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1869 SourceLocation StartLoc, SourceLocation IdLoc,
1870 ClassTemplateDecl *SpecializedTemplate,
1875
1876 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1877 bool Qualified) const override;
1878
1879 // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1880 // different "most recent" declaration from this function for the same
1881 // declaration, because we don't override getMostRecentDeclImpl(). But
1882 // it's not clear that we should override that, because the most recent
1883 // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1885 return cast<ClassTemplateSpecializationDecl>(
1887 }
1888
1889 /// Retrieve the template that this specialization specializes.
1891
1892 /// Retrieve the template arguments of the class template
1893 /// specialization.
1895 return *TemplateArgs;
1896 }
1897
1899 TemplateArgs = Args;
1900 }
1901
1902 /// Determine the kind of specialization that this
1903 /// declaration represents.
1905 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1906 }
1907
1910 }
1911
1912 /// Is this an explicit specialization at class scope (within the class that
1913 /// owns the primary template)? For example:
1914 ///
1915 /// \code
1916 /// template<typename T> struct Outer {
1917 /// template<typename U> struct Inner;
1918 /// template<> struct Inner; // class-scope explicit specialization
1919 /// };
1920 /// \endcode
1922 return isExplicitSpecialization() &&
1923 isa<CXXRecordDecl>(getLexicalDeclContext());
1924 }
1925
1926 /// True if this declaration is an explicit specialization,
1927 /// explicit instantiation declaration, or explicit instantiation
1928 /// definition.
1932 }
1933
1935 SpecializedTemplate = Specialized;
1936 }
1937
1939 SpecializationKind = TSK;
1940 }
1941
1942 /// Get the point of instantiation (if any), or null if none.
1944 return PointOfInstantiation;
1945 }
1946
1948 assert(Loc.isValid() && "point of instantiation must be valid!");
1949 PointOfInstantiation = Loc;
1950 }
1951
1952 /// If this class template specialization is an instantiation of
1953 /// a template (rather than an explicit specialization), return the
1954 /// class template or class template partial specialization from which it
1955 /// was instantiated.
1956 llvm::PointerUnion<ClassTemplateDecl *,
1960 return llvm::PointerUnion<ClassTemplateDecl *,
1962
1964 }
1965
1966 /// Retrieve the class template or class template partial
1967 /// specialization which was specialized by this.
1968 llvm::PointerUnion<ClassTemplateDecl *,
1971 if (const auto *PartialSpec =
1972 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1973 return PartialSpec->PartialSpecialization;
1974
1975 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1976 }
1977
1978 /// Retrieve the set of template arguments that should be used
1979 /// to instantiate members of the class template or class template partial
1980 /// specialization from which this class template specialization was
1981 /// instantiated.
1982 ///
1983 /// \returns For a class template specialization instantiated from the primary
1984 /// template, this function will return the same template arguments as
1985 /// getTemplateArgs(). For a class template specialization instantiated from
1986 /// a class template partial specialization, this function will return the
1987 /// deduced template arguments for the class template partial specialization
1988 /// itself.
1990 if (const auto *PartialSpec =
1991 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1992 return *PartialSpec->TemplateArgs;
1993
1994 return getTemplateArgs();
1995 }
1996
1997 /// Note that this class template specialization is actually an
1998 /// instantiation of the given class template partial specialization whose
1999 /// template arguments have been deduced.
2001 const TemplateArgumentList *TemplateArgs) {
2002 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2003 "Already set to a class template partial specialization!");
2004 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2005 PS->PartialSpecialization = PartialSpec;
2006 PS->TemplateArgs = TemplateArgs;
2007 SpecializedTemplate = PS;
2008 }
2009
2010 /// Note that this class template specialization is an instantiation
2011 /// of the given class template.
2013 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2014 "Previously set to a class template partial specialization!");
2015 SpecializedTemplate = TemplDecl;
2016 }
2017
2018 /// Retrieve the template argument list as written in the sources,
2019 /// if any.
2021 if (auto *Info =
2022 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2023 return Info->TemplateArgsAsWritten;
2024 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2025 }
2026
2027 /// Set the template argument list as written in the sources.
2028 void
2030 if (auto *Info =
2031 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2032 Info->TemplateArgsAsWritten = ArgsWritten;
2033 else
2034 ExplicitInfo = ArgsWritten;
2035 }
2036
2037 /// Set the template argument list as written in the sources.
2041 }
2042
2043 /// Gets the location of the extern keyword, if present.
2045 if (auto *Info =
2046 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2047 return Info->ExternKeywordLoc;
2048 return SourceLocation();
2049 }
2050
2051 /// Sets the location of the extern keyword.
2053
2054 /// Gets the location of the template keyword, if present.
2056 if (auto *Info =
2057 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2058 return Info->TemplateKeywordLoc;
2059 return SourceLocation();
2060 }
2061
2062 /// Sets the location of the template keyword.
2064
2065 SourceRange getSourceRange() const override LLVM_READONLY;
2066
2067 void Profile(llvm::FoldingSetNodeID &ID) const {
2068 Profile(ID, TemplateArgs->asArray(), getASTContext());
2069 }
2070
2071 static void
2072 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2073 const ASTContext &Context) {
2074 ID.AddInteger(TemplateArgs.size());
2075 for (const TemplateArgument &TemplateArg : TemplateArgs)
2076 TemplateArg.Profile(ID, Context);
2077 }
2078
2079 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2080
2081 static bool classofKind(Kind K) {
2082 return K >= firstClassTemplateSpecialization &&
2083 K <= lastClassTemplateSpecialization;
2084 }
2085};
2086
2089 /// The list of template parameters
2090 TemplateParameterList *TemplateParams = nullptr;
2091
2092 /// The class template partial specialization from which this
2093 /// class template partial specialization was instantiated.
2094 ///
2095 /// The boolean value will be true to indicate that this class template
2096 /// partial specialization was specialized at this level.
2097 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2098 InstantiatedFromMember;
2099
2101 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2103 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2105
2107 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2108 InstantiatedFromMember(nullptr, false) {}
2109
2110 void anchor() override;
2111
2112public:
2113 friend class ASTDeclReader;
2114 friend class ASTDeclWriter;
2115
2117 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2118 SourceLocation StartLoc, SourceLocation IdLoc,
2119 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2120 ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
2122
2125
2127 return cast<ClassTemplatePartialSpecializationDecl>(
2128 static_cast<ClassTemplateSpecializationDecl *>(
2129 this)->getMostRecentDecl());
2130 }
2131
2132 /// Get the list of template parameters
2134 return TemplateParams;
2135 }
2136
2137 /// Get the template argument list of the template parameter list.
2139 getInjectedTemplateArgs(const ASTContext &Context) const {
2141 }
2142
2143 /// \brief All associated constraints of this partial specialization,
2144 /// including the requires clause and any constraints derived from
2145 /// constrained-parameters.
2146 ///
2147 /// The constraints in the resulting list are to be treated as if in a
2148 /// conjunction ("and").
2150 TemplateParams->getAssociatedConstraints(AC);
2151 }
2152
2154 return TemplateParams->hasAssociatedConstraints();
2155 }
2156
2157 /// Retrieve the member class template partial specialization from
2158 /// which this particular class template partial specialization was
2159 /// instantiated.
2160 ///
2161 /// \code
2162 /// template<typename T>
2163 /// struct Outer {
2164 /// template<typename U> struct Inner;
2165 /// template<typename U> struct Inner<U*> { }; // #1
2166 /// };
2167 ///
2168 /// Outer<float>::Inner<int*> ii;
2169 /// \endcode
2170 ///
2171 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2172 /// end up instantiating the partial specialization
2173 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2174 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2175 /// \c Outer<float>::Inner<U*>, this function would return
2176 /// \c Outer<T>::Inner<U*>.
2178 const auto *First =
2179 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2180 return First->InstantiatedFromMember.getPointer();
2181 }
2185 }
2186
2189 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2190 First->InstantiatedFromMember.setPointer(PartialSpec);
2191 }
2192
2193 /// Determines whether this class template partial specialization
2194 /// template was a specialization of a member partial specialization.
2195 ///
2196 /// In the following example, the member template partial specialization
2197 /// \c X<int>::Inner<T*> is a member specialization.
2198 ///
2199 /// \code
2200 /// template<typename T>
2201 /// struct X {
2202 /// template<typename U> struct Inner;
2203 /// template<typename U> struct Inner<U*>;
2204 /// };
2205 ///
2206 /// template<> template<typename T>
2207 /// struct X<int>::Inner<T*> { /* ... */ };
2208 /// \endcode
2210 const auto *First =
2211 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2212 return First->InstantiatedFromMember.getInt();
2213 }
2214
2215 /// Note that this member template is a specialization.
2217 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2218 assert(First->InstantiatedFromMember.getPointer() &&
2219 "Only member templates can be member template specializations");
2220 return First->InstantiatedFromMember.setInt(true);
2221 }
2222
2223 /// Retrieves the injected specialization type for this partial
2224 /// specialization. This is not the same as the type-decl-type for
2225 /// this partial specialization, which is an InjectedClassNameType.
2227 assert(getTypeForDecl() && "partial specialization has no type set!");
2228 return cast<InjectedClassNameType>(getTypeForDecl())
2229 ->getInjectedSpecializationType();
2230 }
2231
2232 SourceRange getSourceRange() const override LLVM_READONLY;
2233
2234 void Profile(llvm::FoldingSetNodeID &ID) const {
2236 getASTContext());
2237 }
2238
2239 static void
2240 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2241 TemplateParameterList *TPL, const ASTContext &Context);
2242
2243 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2244
2245 static bool classofKind(Kind K) {
2246 return K == ClassTemplatePartialSpecialization;
2247 }
2248};
2249
2250/// Declaration of a class template.
2252protected:
2253 /// Data that is common to all of the declarations of a given
2254 /// class template.
2256 /// The class template specializations for this class
2257 /// template, including explicit specializations and instantiations.
2258 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2259
2260 /// The class template partial specializations for this class
2261 /// template.
2262 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2264
2265 /// The injected-class-name type for this class template.
2267
2268 Common() = default;
2269 };
2270
2271 /// Retrieve the set of specializations of this class template.
2272 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2273 getSpecializations() const;
2274
2275 /// Retrieve the set of partial specializations of this class
2276 /// template.
2277 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2279
2282 NamedDecl *Decl)
2283 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2284
2285 CommonBase *newCommon(ASTContext &C) const override;
2286
2288 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2289 }
2290
2292
2293public:
2294
2295 friend class ASTDeclReader;
2296 friend class ASTDeclWriter;
2298
2299 /// Load any lazily-loaded specializations from the external source.
2300 void LoadLazySpecializations(bool OnlyPartial = false) const;
2301
2302 /// Get the underlying class declarations of the template.
2304 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2305 }
2306
2307 /// Returns whether this template declaration defines the primary
2308 /// class pattern.
2311 }
2312
2313 /// \brief Create a class template node.
2316 DeclarationName Name,
2317 TemplateParameterList *Params,
2318 NamedDecl *Decl);
2319
2320 /// Create an empty class template node.
2322
2323 /// Return the specialization with the provided arguments if it exists,
2324 /// otherwise return the insertion point.
2326 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2327
2328 /// Insert the specified specialization knowing that it is not already
2329 /// in. InsertPos must be obtained from findSpecialization.
2330 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2331
2333 return cast<ClassTemplateDecl>(
2335 }
2337 return cast<ClassTemplateDecl>(
2339 }
2340
2341 /// Retrieve the previous declaration of this class template, or
2342 /// nullptr if no such declaration exists.
2344 return cast_or_null<ClassTemplateDecl>(
2345 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2346 }
2348 return cast_or_null<ClassTemplateDecl>(
2349 static_cast<const RedeclarableTemplateDecl *>(
2350 this)->getPreviousDecl());
2351 }
2352
2354 return cast<ClassTemplateDecl>(
2355 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2356 }
2358 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2359 }
2360
2362 return cast_or_null<ClassTemplateDecl>(
2364 }
2365
2366 /// Return the partial specialization with the provided arguments if it
2367 /// exists, otherwise return the insertion point.
2370 TemplateParameterList *TPL, void *&InsertPos);
2371
2372 /// Insert the specified partial specialization knowing that it is not
2373 /// already in. InsertPos must be obtained from findPartialSpecialization.
2375 void *InsertPos);
2376
2377 /// Retrieve the partial specializations as an ordered list.
2380
2381 /// Find a class template partial specialization with the given
2382 /// type T.
2383 ///
2384 /// \param T a dependent type that names a specialization of this class
2385 /// template.
2386 ///
2387 /// \returns the class template partial specialization that exactly matches
2388 /// the type \p T, or nullptr if no such partial specialization exists.
2390
2391 /// Find a class template partial specialization which was instantiated
2392 /// from the given member partial specialization.
2393 ///
2394 /// \param D a member class template partial specialization.
2395 ///
2396 /// \returns the class template partial specialization which was instantiated
2397 /// from the given member partial specialization, or nullptr if no such
2398 /// partial specialization exists.
2402
2403 /// Retrieve the template specialization type of the
2404 /// injected-class-name for this class template.
2405 ///
2406 /// The injected-class-name for a class template \c X is \c
2407 /// X<template-args>, where \c template-args is formed from the
2408 /// template arguments that correspond to the template parameters of
2409 /// \c X. For example:
2410 ///
2411 /// \code
2412 /// template<typename T, int N>
2413 /// struct array {
2414 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2415 /// };
2416 /// \endcode
2418
2420 using spec_range = llvm::iterator_range<spec_iterator>;
2421
2423 return spec_range(spec_begin(), spec_end());
2424 }
2425
2427 return makeSpecIterator(getSpecializations(), false);
2428 }
2429
2431 return makeSpecIterator(getSpecializations(), true);
2432 }
2433
2434 // Implement isa/cast/dyncast support
2435 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2436 static bool classofKind(Kind K) { return K == ClassTemplate; }
2437};
2438
2439/// Declaration of a friend template.
2440///
2441/// For example:
2442/// \code
2443/// template <typename T> class A {
2444/// friend class MyVector<T>; // not a friend template
2445/// template <typename U> friend class B; // not a friend template
2446/// template <typename U> friend class Foo<T>::Nested; // friend template
2447/// };
2448/// \endcode
2449///
2450/// \note This class is not currently in use. All of the above
2451/// will yield a FriendDecl, not a FriendTemplateDecl.
2452class FriendTemplateDecl : public Decl {
2453 virtual void anchor();
2454
2455public:
2456 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2457
2458private:
2459 // The number of template parameters; always non-zero.
2460 unsigned NumParams = 0;
2461
2462 // The parameter list.
2463 TemplateParameterList **Params = nullptr;
2464
2465 // The declaration that's a friend of this class.
2466 FriendUnion Friend;
2467
2468 // Location of the 'friend' specifier.
2469 SourceLocation FriendLoc;
2470
2472 TemplateParameterList **Params, unsigned NumParams,
2473 FriendUnion Friend, SourceLocation FriendLoc)
2474 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2475 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2476
2477 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2478
2479public:
2480 friend class ASTDeclReader;
2481
2482 static FriendTemplateDecl *
2485 SourceLocation FriendLoc);
2486
2488
2489 /// If this friend declaration names a templated type (or
2490 /// a dependent member type of a templated type), return that
2491 /// type; otherwise return null.
2493 return Friend.dyn_cast<TypeSourceInfo*>();
2494 }
2495
2496 /// If this friend declaration names a templated function (or
2497 /// a member function of a templated type), return that type;
2498 /// otherwise return null.
2500 return Friend.dyn_cast<NamedDecl*>();
2501 }
2502
2503 /// Retrieves the location of the 'friend' keyword.
2505 return FriendLoc;
2506 }
2507
2509 assert(i <= NumParams);
2510 return Params[i];
2511 }
2512
2513 unsigned getNumTemplateParameters() const {
2514 return NumParams;
2515 }
2516
2517 // Implement isa/cast/dyncast/etc.
2518 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2519 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2520};
2521
2522/// Declaration of an alias template.
2523///
2524/// For example:
2525/// \code
2526/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2527/// \endcode
2529protected:
2531
2534 NamedDecl *Decl)
2535 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2536 Decl) {}
2537
2538 CommonBase *newCommon(ASTContext &C) const override;
2539
2541 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2542 }
2543
2544public:
2545 friend class ASTDeclReader;
2546 friend class ASTDeclWriter;
2547
2548 /// Get the underlying function declaration of the template.
2550 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2551 }
2552
2553
2555 return cast<TypeAliasTemplateDecl>(
2557 }
2559 return cast<TypeAliasTemplateDecl>(
2561 }
2562
2563 /// Retrieve the previous declaration of this function template, or
2564 /// nullptr if no such declaration exists.
2566 return cast_or_null<TypeAliasTemplateDecl>(
2567 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2568 }
2570 return cast_or_null<TypeAliasTemplateDecl>(
2571 static_cast<const RedeclarableTemplateDecl *>(
2572 this)->getPreviousDecl());
2573 }
2574
2576 return cast_or_null<TypeAliasTemplateDecl>(
2578 }
2579
2580 /// Create a function template node.
2583 DeclarationName Name,
2584 TemplateParameterList *Params,
2585 NamedDecl *Decl);
2586
2587 /// Create an empty alias template node.
2590
2591 // Implement isa/cast/dyncast support
2592 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2593 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2594};
2595
2596/// Represents a variable template specialization, which refers to
2597/// a variable template with a given set of template arguments.
2598///
2599/// Variable template specializations represent both explicit
2600/// specializations of variable templates, as in the example below, and
2601/// implicit instantiations of variable templates.
2602///
2603/// \code
2604/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2605///
2606/// template<>
2607/// constexpr float pi<float>; // variable template specialization pi<float>
2608/// \endcode
2610 public llvm::FoldingSetNode {
2611
2612 /// Structure that stores information about a variable template
2613 /// specialization that was instantiated from a variable template partial
2614 /// specialization.
2615 struct SpecializedPartialSpecialization {
2616 /// The variable template partial specialization from which this
2617 /// variable template specialization was instantiated.
2618 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2619
2620 /// The template argument list deduced for the variable template
2621 /// partial specialization itself.
2622 const TemplateArgumentList *TemplateArgs;
2623 };
2624
2625 /// The template that this specialization specializes.
2626 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2627 SpecializedTemplate;
2628
2629 /// Further info for explicit template specialization/instantiation.
2630 /// Does not apply to implicit specializations.
2631 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2632
2633 /// The template arguments used to describe this specialization.
2634 const TemplateArgumentList *TemplateArgs;
2635
2636 /// The point where this template was instantiated (if any).
2637 SourceLocation PointOfInstantiation;
2638
2639 /// The kind of specialization this declaration refers to.
2640 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2641 unsigned SpecializationKind : 3;
2642
2643 /// Whether this declaration is a complete definition of the
2644 /// variable template specialization. We can't otherwise tell apart
2645 /// an instantiated declaration from an instantiated definition with
2646 /// no initializer.
2647 LLVM_PREFERRED_TYPE(bool)
2648 unsigned IsCompleteDefinition : 1;
2649
2650protected:
2652 SourceLocation StartLoc, SourceLocation IdLoc,
2653 VarTemplateDecl *SpecializedTemplate,
2654 QualType T, TypeSourceInfo *TInfo,
2655 StorageClass S,
2657
2658 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2659
2660public:
2661 friend class ASTDeclReader;
2662 friend class ASTDeclWriter;
2663 friend class VarDecl;
2664
2666 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2667 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2668 TypeSourceInfo *TInfo, StorageClass S,
2672
2673 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2674 bool Qualified) const override;
2675
2677 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2678 return cast<VarTemplateSpecializationDecl>(Recent);
2679 }
2680
2681 /// Retrieve the template that this specialization specializes.
2683
2684 /// Retrieve the template arguments of the variable template
2685 /// specialization.
2686 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2687
2688 /// Determine the kind of specialization that this
2689 /// declaration represents.
2691 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2692 }
2693
2696 }
2697
2699 return isExplicitSpecialization() &&
2700 isa<CXXRecordDecl>(getLexicalDeclContext());
2701 }
2702
2703 /// True if this declaration is an explicit specialization,
2704 /// explicit instantiation declaration, or explicit instantiation
2705 /// definition.
2709 }
2710
2712 SpecializationKind = TSK;
2713 }
2714
2715 /// Get the point of instantiation (if any), or null if none.
2717 return PointOfInstantiation;
2718 }
2719
2721 assert(Loc.isValid() && "point of instantiation must be valid!");
2722 PointOfInstantiation = Loc;
2723 }
2724
2725 void setCompleteDefinition() { IsCompleteDefinition = true; }
2726
2727 /// If this variable template specialization is an instantiation of
2728 /// a template (rather than an explicit specialization), return the
2729 /// variable template or variable template partial specialization from which
2730 /// it was instantiated.
2731 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2734 return llvm::PointerUnion<VarTemplateDecl *,
2736
2738 }
2739
2740 /// Retrieve the variable template or variable template partial
2741 /// specialization which was specialized by this.
2742 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2744 if (const auto *PartialSpec =
2745 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2746 return PartialSpec->PartialSpecialization;
2747
2748 return cast<VarTemplateDecl *>(SpecializedTemplate);
2749 }
2750
2751 /// Retrieve the set of template arguments that should be used
2752 /// to instantiate the initializer of the variable template or variable
2753 /// template partial specialization from which this variable template
2754 /// specialization was instantiated.
2755 ///
2756 /// \returns For a variable template specialization instantiated from the
2757 /// primary template, this function will return the same template arguments
2758 /// as getTemplateArgs(). For a variable template specialization instantiated
2759 /// from a variable template partial specialization, this function will the
2760 /// return deduced template arguments for the variable template partial
2761 /// specialization itself.
2763 if (const auto *PartialSpec =
2764 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2765 return *PartialSpec->TemplateArgs;
2766
2767 return getTemplateArgs();
2768 }
2769
2770 /// Note that this variable template specialization is actually an
2771 /// instantiation of the given variable template partial specialization whose
2772 /// template arguments have been deduced.
2774 const TemplateArgumentList *TemplateArgs) {
2775 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2776 "Already set to a variable template partial specialization!");
2777 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2778 PS->PartialSpecialization = PartialSpec;
2779 PS->TemplateArgs = TemplateArgs;
2780 SpecializedTemplate = PS;
2781 }
2782
2783 /// Note that this variable template specialization is an instantiation
2784 /// of the given variable template.
2786 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2787 "Previously set to a variable template partial specialization!");
2788 SpecializedTemplate = TemplDecl;
2789 }
2790
2791 /// Retrieve the template argument list as written in the sources,
2792 /// if any.
2794 if (auto *Info =
2795 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2796 return Info->TemplateArgsAsWritten;
2797 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2798 }
2799
2800 /// Set the template argument list as written in the sources.
2801 void
2803 if (auto *Info =
2804 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2805 Info->TemplateArgsAsWritten = ArgsWritten;
2806 else
2807 ExplicitInfo = ArgsWritten;
2808 }
2809
2810 /// Set the template argument list as written in the sources.
2814 }
2815
2816 /// Gets the location of the extern keyword, if present.
2818 if (auto *Info =
2819 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2820 return Info->ExternKeywordLoc;
2821 return SourceLocation();
2822 }
2823
2824 /// Sets the location of the extern keyword.
2826
2827 /// Gets the location of the template keyword, if present.
2829 if (auto *Info =
2830 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2831 return Info->TemplateKeywordLoc;
2832 return SourceLocation();
2833 }
2834
2835 /// Sets the location of the template keyword.
2837
2838 SourceRange getSourceRange() const override LLVM_READONLY;
2839
2840 void Profile(llvm::FoldingSetNodeID &ID) const {
2841 Profile(ID, TemplateArgs->asArray(), getASTContext());
2842 }
2843
2844 static void Profile(llvm::FoldingSetNodeID &ID,
2845 ArrayRef<TemplateArgument> TemplateArgs,
2846 const ASTContext &Context) {
2847 ID.AddInteger(TemplateArgs.size());
2848 for (const TemplateArgument &TemplateArg : TemplateArgs)
2849 TemplateArg.Profile(ID, Context);
2850 }
2851
2852 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2853
2854 static bool classofKind(Kind K) {
2855 return K >= firstVarTemplateSpecialization &&
2856 K <= lastVarTemplateSpecialization;
2857 }
2858};
2859
2862 /// The list of template parameters
2863 TemplateParameterList *TemplateParams = nullptr;
2864
2865 /// The variable template partial specialization from which this
2866 /// variable template partial specialization was instantiated.
2867 ///
2868 /// The boolean value will be true to indicate that this variable template
2869 /// partial specialization was specialized at this level.
2870 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2871 InstantiatedFromMember;
2872
2874 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2876 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2878
2880 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2881 Context),
2882 InstantiatedFromMember(nullptr, false) {}
2883
2884 void anchor() override;
2885
2886public:
2887 friend class ASTDeclReader;
2888 friend class ASTDeclWriter;
2889
2891 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2893 VarTemplateDecl *SpecializedTemplate, QualType T,
2894 TypeSourceInfo *TInfo, StorageClass S,
2896
2899
2901 return cast<VarTemplatePartialSpecializationDecl>(
2902 static_cast<VarTemplateSpecializationDecl *>(
2903 this)->getMostRecentDecl());
2904 }
2905
2906 /// Get the list of template parameters
2908 return TemplateParams;
2909 }
2910
2911 /// Get the template argument list of the template parameter list.
2913 getInjectedTemplateArgs(const ASTContext &Context) const {
2915 }
2916
2917 /// \brief All associated constraints of this partial specialization,
2918 /// including the requires clause and any constraints derived from
2919 /// constrained-parameters.
2920 ///
2921 /// The constraints in the resulting list are to be treated as if in a
2922 /// conjunction ("and").
2924 TemplateParams->getAssociatedConstraints(AC);
2925 }
2926
2928 return TemplateParams->hasAssociatedConstraints();
2929 }
2930
2931 /// \brief Retrieve the member variable template partial specialization from
2932 /// which this particular variable template partial specialization was
2933 /// instantiated.
2934 ///
2935 /// \code
2936 /// template<typename T>
2937 /// struct Outer {
2938 /// template<typename U> U Inner;
2939 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2940 /// };
2941 ///
2942 /// template int* Outer<float>::Inner<int*>;
2943 /// \endcode
2944 ///
2945 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2946 /// end up instantiating the partial specialization
2947 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2948 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2949 /// \c Outer<float>::Inner<U*>, this function would return
2950 /// \c Outer<T>::Inner<U*>.
2952 const auto *First =
2953 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2954 return First->InstantiatedFromMember.getPointer();
2955 }
2956
2957 void
2959 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2960 First->InstantiatedFromMember.setPointer(PartialSpec);
2961 }
2962
2963 /// Determines whether this variable template partial specialization
2964 /// was a specialization of a member partial specialization.
2965 ///
2966 /// In the following example, the member template partial specialization
2967 /// \c X<int>::Inner<T*> is a member specialization.
2968 ///
2969 /// \code
2970 /// template<typename T>
2971 /// struct X {
2972 /// template<typename U> U Inner;
2973 /// template<typename U> U* Inner<U*> = (U*)(0);
2974 /// };
2975 ///
2976 /// template<> template<typename T>
2977 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2978 /// \endcode
2980 const auto *First =
2981 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2982 return First->InstantiatedFromMember.getInt();
2983 }
2984
2985 /// Note that this member template is a specialization.
2987 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2988 assert(First->InstantiatedFromMember.getPointer() &&
2989 "Only member templates can be member template specializations");
2990 return First->InstantiatedFromMember.setInt(true);
2991 }
2992
2993 SourceRange getSourceRange() const override LLVM_READONLY;
2994
2995 void Profile(llvm::FoldingSetNodeID &ID) const {
2997 getASTContext());
2998 }
2999
3000 static void
3001 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3002 TemplateParameterList *TPL, const ASTContext &Context);
3003
3004 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3005
3006 static bool classofKind(Kind K) {
3007 return K == VarTemplatePartialSpecialization;
3008 }
3009};
3010
3011/// Declaration of a variable template.
3013protected:
3014 /// Data that is common to all of the declarations of a given
3015 /// variable template.
3017 /// The variable template specializations for this variable
3018 /// template, including explicit specializations and instantiations.
3019 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3020
3021 /// The variable template partial specializations for this variable
3022 /// template.
3023 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3025
3026 Common() = default;
3027 };
3028
3029 /// Retrieve the set of specializations of this variable template.
3030 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3031 getSpecializations() const;
3032
3033 /// Retrieve the set of partial specializations of this class
3034 /// template.
3035 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3037
3040 NamedDecl *Decl)
3041 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3042
3043 CommonBase *newCommon(ASTContext &C) const override;
3044
3046 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3047 }
3048
3049public:
3050 friend class ASTDeclReader;
3051 friend class ASTDeclWriter;
3052
3053 /// Load any lazily-loaded specializations from the external source.
3054 void LoadLazySpecializations(bool OnlyPartial = false) const;
3055
3056 /// Get the underlying variable declarations of the template.
3058 return static_cast<VarDecl *>(TemplatedDecl);
3059 }
3060
3061 /// Returns whether this template declaration defines the primary
3062 /// variable pattern.
3065 }
3066
3068
3069 /// Create a variable template node.
3072 TemplateParameterList *Params,
3073 VarDecl *Decl);
3074
3075 /// Create an empty variable template node.
3077
3078 /// Return the specialization with the provided arguments if it exists,
3079 /// otherwise return the insertion point.
3081 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3082
3083 /// Insert the specified specialization knowing that it is not already
3084 /// in. InsertPos must be obtained from findSpecialization.
3085 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3086
3088 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3089 }
3091 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3092 }
3093
3094 /// Retrieve the previous declaration of this variable template, or
3095 /// nullptr if no such declaration exists.
3097 return cast_or_null<VarTemplateDecl>(
3098 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3099 }
3101 return cast_or_null<VarTemplateDecl>(
3102 static_cast<const RedeclarableTemplateDecl *>(
3103 this)->getPreviousDecl());
3104 }
3105
3107 return cast<VarTemplateDecl>(
3108 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3109 }
3111 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3112 }
3113
3115 return cast_or_null<VarTemplateDecl>(
3117 }
3118
3119 /// Return the partial specialization with the provided arguments if it
3120 /// exists, otherwise return the insertion point.
3123 TemplateParameterList *TPL, void *&InsertPos);
3124
3125 /// Insert the specified partial specialization knowing that it is not
3126 /// already in. InsertPos must be obtained from findPartialSpecialization.
3128 void *InsertPos);
3129
3130 /// Retrieve the partial specializations as an ordered list.
3133
3134 /// Find a variable template partial specialization which was
3135 /// instantiated
3136 /// from the given member partial specialization.
3137 ///
3138 /// \param D a member variable template partial specialization.
3139 ///
3140 /// \returns the variable template partial specialization which was
3141 /// instantiated
3142 /// from the given member partial specialization, or nullptr if no such
3143 /// partial specialization exists.
3146
3148 using spec_range = llvm::iterator_range<spec_iterator>;
3149
3151 return spec_range(spec_begin(), spec_end());
3152 }
3153
3155 return makeSpecIterator(getSpecializations(), false);
3156 }
3157
3159 return makeSpecIterator(getSpecializations(), true);
3160 }
3161
3162 // Implement isa/cast/dyncast support
3163 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3164 static bool classofKind(Kind K) { return K == VarTemplate; }
3165};
3166
3167/// Declaration of a C++20 concept.
3168class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3169protected:
3171
3174 : TemplateDecl(Concept, DC, L, Name, Params),
3176public:
3178 DeclarationName Name,
3179 TemplateParameterList *Params,
3180 Expr *ConstraintExpr = nullptr);
3182
3184 return ConstraintExpr;
3185 }
3186
3187 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3188
3190
3191 SourceRange getSourceRange() const override LLVM_READONLY {
3192 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3194 : SourceLocation());
3195 }
3196
3197 bool isTypeConcept() const {
3198 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3199 }
3200
3202 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3203 }
3205 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3206 }
3207
3208 // Implement isa/cast/dyncast/etc.
3209 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3210 static bool classofKind(Kind K) { return K == Concept; }
3211
3212 friend class ASTReader;
3213 friend class ASTDeclReader;
3214 friend class ASTDeclWriter;
3215};
3216
3217// An implementation detail of ConceptSpecialicationExpr that holds the template
3218// arguments, so we can later use this to reconstitute the template arguments
3219// during constraint checking.
3221 : public Decl,
3222 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3223 TemplateArgument> {
3224 unsigned NumTemplateArgs;
3225
3227 ArrayRef<TemplateArgument> ConvertedArgs);
3228 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3229
3230public:
3233 ArrayRef<TemplateArgument> ConvertedArgs);
3236 unsigned NumTemplateArgs);
3237
3239 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3240 NumTemplateArgs);
3241 }
3243
3244 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3245 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3246
3248 friend class ASTDeclReader;
3249};
3250
3251/// A template parameter object.
3252///
3253/// Template parameter objects represent values of class type used as template
3254/// arguments. There is one template parameter object for each such distinct
3255/// value used as a template argument across the program.
3256///
3257/// \code
3258/// struct A { int x, y; };
3259/// template<A> struct S;
3260/// S<A{1, 2}> s1;
3261/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3262/// \endcode
3264 public Mergeable<TemplateParamObjectDecl>,
3265 public llvm::FoldingSetNode {
3266private:
3267 /// The value of this template parameter object.
3268 APValue Value;
3269
3271 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3272 T),
3273 Value(V) {}
3274
3276 const APValue &V);
3277 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3279
3280 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3281 /// create these.
3282 friend class ASTContext;
3283 friend class ASTReader;
3284 friend class ASTDeclReader;
3285
3286public:
3287 /// Print this template parameter object in a human-readable format.
3288 void printName(llvm::raw_ostream &OS,
3289 const PrintingPolicy &Policy) const override;
3290
3291 /// Print this object as an equivalent expression.
3292 void printAsExpr(llvm::raw_ostream &OS) const;
3293 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3294
3295 /// Print this object as an initializer suitable for a variable of the
3296 /// object's type.
3297 void printAsInit(llvm::raw_ostream &OS) const;
3298 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3299
3300 const APValue &getValue() const { return Value; }
3301
3302 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3303 const APValue &V) {
3304 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3305 V.Profile(ID);
3306 }
3307 void Profile(llvm::FoldingSetNodeID &ID) {
3308 Profile(ID, getType(), getValue());
3309 }
3310
3312 return getFirstDecl();
3313 }
3315 return getFirstDecl();
3316 }
3317
3318 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3319 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3320};
3321
3323 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3324 return PD;
3325 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3326 return PD;
3327 return cast<TemplateTemplateParmDecl *>(P);
3328}
3329
3331 auto *TD = dyn_cast<TemplateDecl>(D);
3332 return TD && (isa<ClassTemplateDecl>(TD) ||
3333 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3334 isa<TypeAliasTemplateDecl>(TD) ||
3335 isa<TemplateTemplateParmDecl>(TD))
3336 ? TD
3337 : nullptr;
3338}
3339
3340/// Check whether the template parameter is a pack expansion, and if so,
3341/// determine the number of parameters produced by that expansion. For instance:
3342///
3343/// \code
3344/// template<typename ...Ts> struct A {
3345/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3346/// };
3347/// \endcode
3348///
3349/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3350/// is not a pack expansion, so returns an empty Optional.
3351inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3352 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3353 if (TTP->isExpandedParameterPack())
3354 return TTP->getNumExpansionParameters();
3355 }
3356
3357 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3358 if (NTTP->isExpandedParameterPack())
3359 return NTTP->getNumExpansionTypes();
3360 }
3361
3362 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3363 if (TTP->isExpandedParameterPack())
3364 return TTP->getNumExpansionTemplateParameters();
3365 }
3366
3367 return std::nullopt;
3368}
3369
3370/// Internal helper used by Subst* nodes to retrieve the parameter list
3371/// for their AssociatedDecl.
3372TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3373
3374} // namespace clang
3375
3376#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3460
StringRef P
static char ID
Definition: Arena.cpp:183
const Decl * D
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
Expr * E
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.
uint32_t Id
Definition: SemaARM.cpp:1122
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
__device__ int
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:188
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:384
bool isConstrained() const
Definition: Type.h:6581
Represents the builtin template declaration which is used to implement __make_integer_seq and other b...
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)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getMostRecentNonInjectedDecl()
Definition: DeclCXX.h:550
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition: DeclCXX.cpp:2012
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 this template.
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.
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
void setCommonPtr(Common *C)
spec_range specializations() const
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
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()
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &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.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void setMemberSpecialization()
Note that this member template is a specialization.
QualType getInjectedSpecializationType() const
Retrieves the injected specialization type for this partial specialization.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?...
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
static bool classof(const Decl *D)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
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)
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasDefinition() const
static bool classof(const Decl *D)
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:124
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1439
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:528
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:596
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
SourceLocation getLocation() const
Definition: DeclBase.h:442
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:911
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:430
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:739
Storage for a default argument.
Definition: DeclTemplate.h:305
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
Definition: DeclTemplate.h:365
bool isSet() const
Determine whether there is a default argument for this parameter.
Definition: DeclTemplate.h:331
ArgType get() const
Get the default argument's value.
Definition: DeclTemplate.h:339
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:359
void clear()
Remove the default argument, even if it was inherited.
Definition: DeclTemplate.h:384
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
Definition: DeclTemplate.h:350
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
Definition: DeclTemplate.h:335
Provides information about a dependent function-template specialization declaration.
Definition: DeclTemplate.h:693
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
Definition: DeclTemplate.h:712
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:705
This represents one expression.
Definition: Expr.h:110
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Definition: DeclTemplate.h:228
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Definition: DeclTemplate.h:235
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:1935
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2249
void setInstantiatedFromMemberTemplate(bool Val=true)
Definition: Decl.h:2304
bool isInstantiatedFromMemberTemplate() const
Definition: Decl.h:2301
Declaration of a template function.
Definition: DeclTemplate.h:958
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
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
Definition: DeclTemplate.h:980
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
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:972
bool isCompatibleWithDefinition() const
const FunctionTemplateDecl * getMostRecentDecl() const
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:471
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
Definition: DeclTemplate.h:485
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:546
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
Definition: DeclTemplate.h:608
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
Definition: DeclTemplate.h:526
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
Definition: DeclTemplate.h:597
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:489
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
Definition: DeclTemplate.h:557
void Profile(llvm::FoldingSetNodeID &ID)
Definition: DeclTemplate.h:603
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
Definition: DeclTemplate.h:493
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
Definition: DeclTemplate.h:523
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:529
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
Definition: DeclTemplate.h:563
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
Definition: DeclTemplate.h:540
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
static bool classof(const Decl *D)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:619
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:650
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:641
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
Definition: DeclTemplate.h:659
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
Definition: DeclTemplate.h:629
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Definition: DeclTemplate.h:664
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
Definition: DeclTemplate.h:638
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
Definition: Redeclarable.h:313
TemplateParamObjectDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:319
This represents a decl that may have a name.
Definition: Decl.h:253
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)
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.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
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...
Represents a pack expansion of types.
Definition: Type.h:7147
A (possibly-)qualified type.
Definition: Type.h:929
Declaration of a redeclarable template.
Definition: DeclTemplate.h:720
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
Definition: DeclTemplate.h:773
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:821
redeclarable_base::redecl_iterator redecl_iterator
Definition: DeclTemplate.h:926
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:858
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
const RedeclarableTemplateDecl * getCanonicalDecl() const
Definition: DeclTemplate.h:836
redeclarable_base::redecl_range redecl_range
Definition: DeclTemplate.h:925
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:811
static bool classof(const Decl *D)
Definition: DeclTemplate.h:936
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
Definition: DeclTemplate.h:905
static bool classofKind(Kind K)
Definition: DeclTemplate.h:938
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:833
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
Definition: DeclTemplate.h:863
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
Definition: DeclTemplate.h:909
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Definition: DeclTemplate.h:921
Provides common interface for the Decls that can be redeclared.
Definition: Redeclarable.h:84
RedeclarableTemplateDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:215
RedeclarableTemplateDecl * getNextRedeclaration() const
Definition: Redeclarable.h:187
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:203
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:291
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:225
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:222
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:295
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:466
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:358
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3683
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:250
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
Definition: DeclTemplate.h:289
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:277
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.
Definition: DeclTemplate.h:286
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:271
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:280
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:61
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:398
NamedDecl * TemplatedDecl
Definition: DeclTemplate.h:448
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:449
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
Definition: DeclTemplate.h:457
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:430
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:442
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
Definition: DeclTemplate.h:408
void setTemplateParameters(TemplateParameterList *TParams)
Definition: DeclTemplate.h:452
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
static bool classof(const Decl *D)
Definition: DeclTemplate.h:436
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:417
static bool classofKind(Kind K)
Definition: DeclTemplate.h:438
A template parameter object.
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)
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.
Definition: DeclTemplate.h:73
const_iterator end() const
Definition: DeclTemplate.h:137
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:147
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:209
const_iterator begin() const
Definition: DeclTemplate.h:135
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
const Expr * getRequiresClause() const
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:188
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
size_t numTrailingObjects(OverloadToken< Expr * >) const
Definition: DeclTemplate.h:110
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
Definition: DeclTemplate.h:175
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.
Definition: DeclTemplate.h:132
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:183
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
Definition: DeclTemplate.h:207
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
Definition: DeclTemplate.h:151
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
Definition: DeclTemplate.h:206
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
Definition: DeclTemplate.h:106
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< const Expr * > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:142
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:205
ArrayRef< const NamedDecl * > asArray() const
Definition: DeclTemplate.h:143
Defines the position of a template parameter within a template parameter list.
static constexpr unsigned MaxPosition
static constexpr unsigned MaxDepth
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
void setPosition(unsigned P)
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
TemplateParmPosition(unsigned D, unsigned P)
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
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.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
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.
bool isExpandedParameterPack() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
void removeDefaultArgument()
Removes the default argument 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 setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
unsigned getNumExpansionParameters() const
Retrieves the number of parameters in an expanded parameter pack.
static bool classofKind(Kind K)
static bool classof(const Decl *D)
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
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:3556
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
Represents a declaration of a type.
Definition: Decl.h:3391
const Type * getTypeForDecl() const
Definition: Decl.h:3416
A container of type source information.
Definition: Type.h:7908
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2812
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8741
A set of unresolved declarations.
Definition: UnresolvedSet.h:62
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
Represents a variable declaration or definition.
Definition: Decl.h:886
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2249
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition: Decl.cpp:2751
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
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 Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Get the template argument list of the template parameter list.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
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.
void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)
Set the template argument list as written in the sources.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...
static bool classof(const Decl *D)
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this variable template specialization is actually an instantiation of the given variable te...
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo)
Set the template argument list as written in the sources.
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
void setInstantiationOf(VarTemplateDecl *TemplDecl)
Note that this variable template specialization is an instantiation of the given variable template.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this variable template specialization is an instantiation of a template (rather than an explicit s...
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
VarTemplateSpecializationDecl * getMostRecentDecl()
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition: Specifiers.h:212
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition: Decl.cpp:76
NamedDecl * getAsNamedDecl(TemplateParameter P)
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
StorageClass
Storage classes.
Definition: Specifiers.h:248
void * allocateDefaultArgStorageChain(const ASTContext &C)
TemplateDecl * getAsTypeTemplateDecl(Decl *D)
llvm::PointerUnion< const ASTTemplateArgumentListInfo *, ExplicitInstantiationInfo * > SpecializationOrInstantiationInfo
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:6877
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:308
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
Definition: DeclTemplate.h:65
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
const FunctionProtoType * T
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:188
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition: Specifiers.h:219
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
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...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
SourceLocation ExternKeywordLoc
The location of the extern keyword.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
SourceLocation TemplateKeywordLoc
The location of the template keyword.
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:964
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:967
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
llvm::PointerIntPair< RedeclarableTemplateDecl *, 1, bool > InstantiatedFromMember
The template from which this was most directly instantiated (or null).
Definition: DeclTemplate.h:806
static ArrayRef< TemplateArgument > getTemplateArgs(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:952
static DeclType * getDecl(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:947
static ArrayRef< TemplateArgument > getTemplateArgs(EntryType *D)
Definition: DeclTemplate.h:745
static DeclType * getDecl(EntryType *D)
Definition: DeclTemplate.h:741
SpecIterator(typename llvm::FoldingSetVector< EntryType >::iterator SetIter)
Definition: DeclTemplate.h:760
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 ...