clang 19.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 location of the 'template' keyword.
75 SourceLocation TemplateLoc;
76
77 /// The locations of the '<' and '>' angle brackets.
78 SourceLocation LAngleLoc, RAngleLoc;
79
80 /// The number of template parameters in this template
81 /// parameter list.
82 unsigned NumParams : 29;
83
84 /// Whether this template parameter list contains an unexpanded parameter
85 /// pack.
86 LLVM_PREFERRED_TYPE(bool)
87 unsigned ContainsUnexpandedParameterPack : 1;
88
89 /// Whether this template parameter list has a requires clause.
90 LLVM_PREFERRED_TYPE(bool)
91 unsigned HasRequiresClause : 1;
92
93 /// Whether any of the template parameters has constrained-parameter
94 /// constraint-expression.
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned HasConstrainedParameters : 1;
97
98protected:
100 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
101 SourceLocation RAngleLoc, Expr *RequiresClause);
102
103 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
104 return NumParams;
105 }
106
107 size_t numTrailingObjects(OverloadToken<Expr *>) const {
108 return HasRequiresClause ? 1 : 0;
109 }
110
111public:
112 template <size_t N, bool HasRequiresClause>
115
117 SourceLocation TemplateLoc,
118 SourceLocation LAngleLoc,
120 SourceLocation RAngleLoc,
121 Expr *RequiresClause);
122
123 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
124
125 /// Iterates through the template parameters in this list.
126 using iterator = NamedDecl **;
127
128 /// Iterates through the template parameters in this list.
129 using const_iterator = NamedDecl * const *;
130
131 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
132 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
133 iterator end() { return begin() + NumParams; }
134 const_iterator end() const { return begin() + NumParams; }
135
136 unsigned size() const { return NumParams; }
137 bool empty() const { return NumParams == 0; }
138
141 return llvm::ArrayRef(begin(), size());
142 }
143
144 NamedDecl* getParam(unsigned Idx) {
145 assert(Idx < size() && "Template parameter index out-of-range");
146 return begin()[Idx];
147 }
148 const NamedDecl* getParam(unsigned Idx) const {
149 assert(Idx < size() && "Template parameter index out-of-range");
150 return begin()[Idx];
151 }
152
153 /// Returns the minimum number of arguments needed to form a
154 /// template specialization.
155 ///
156 /// This may be fewer than the number of template parameters, if some of
157 /// the parameters have default arguments or if there is a parameter pack.
158 unsigned getMinRequiredArguments() const;
159
160 /// Get the depth of this template parameter list in the set of
161 /// template parameter lists.
162 ///
163 /// The first template parameter list in a declaration will have depth 0,
164 /// the second template parameter list will have depth 1, etc.
165 unsigned getDepth() const;
166
167 /// Determine whether this template parameter list contains an
168 /// unexpanded parameter pack.
170
171 /// Determine whether this template parameter list contains a parameter pack.
172 bool hasParameterPack() const {
173 for (const NamedDecl *P : asArray())
174 if (P->isParameterPack())
175 return true;
176 return false;
177 }
178
179 /// The constraint-expression of the associated requires-clause.
181 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
182 }
183
184 /// The constraint-expression of the associated requires-clause.
185 const Expr *getRequiresClause() const {
186 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
187 }
188
189 /// \brief All associated constraints derived from this template parameter
190 /// list, including the requires clause and any constraints derived from
191 /// constrained-parameters.
192 ///
193 /// The constraints in the resulting list are to be treated as if in a
194 /// conjunction ("and").
196
198
199 SourceLocation getTemplateLoc() const { return TemplateLoc; }
200 SourceLocation getLAngleLoc() const { return LAngleLoc; }
201 SourceLocation getRAngleLoc() const { return RAngleLoc; }
202
203 SourceRange getSourceRange() const LLVM_READONLY {
204 return SourceRange(TemplateLoc, RAngleLoc);
205 }
206
207 void print(raw_ostream &Out, const ASTContext &Context,
208 bool OmitTemplateKW = false) const;
209 void print(raw_ostream &Out, const ASTContext &Context,
210 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
211
213 const TemplateParameterList *TPL,
214 unsigned Idx);
215};
216
217/// Stores a list of template parameters and the associated
218/// requires-clause (if any) for a TemplateDecl and its derived classes.
219/// Suitable for creating on the stack.
220template <size_t N, bool HasRequiresClause>
222 : public TemplateParameterList::FixedSizeStorageOwner {
223 typename TemplateParameterList::FixedSizeStorage<
224 NamedDecl *, Expr *>::with_counts<
225 N, HasRequiresClause ? 1u : 0u
226 >::type storage;
227
228public:
230 SourceLocation TemplateLoc,
231 SourceLocation LAngleLoc,
233 SourceLocation RAngleLoc,
234 Expr *RequiresClause)
235 : FixedSizeStorageOwner(
236 (assert(N == Params.size()),
237 assert(HasRequiresClause == (RequiresClause != nullptr)),
238 new (static_cast<void *>(&storage)) TemplateParameterList(C,
239 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
240};
241
242/// A template argument list.
244 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
245 /// The number of template arguments in this template
246 /// argument list.
247 unsigned NumArguments;
248
249 // Constructs an instance with an internal Argument list, containing
250 // a copy of the Args array. (Called by CreateCopy)
252
253public:
255
258
259 /// Create a new template argument list that copies the given set of
260 /// template arguments.
263
264 /// Retrieve the template argument at a given index.
265 const TemplateArgument &get(unsigned Idx) const {
266 assert(Idx < NumArguments && "Invalid template argument index");
267 return data()[Idx];
268 }
269
270 /// Retrieve the template argument at a given index.
271 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
272
273 /// Produce this as an array ref.
275 return llvm::ArrayRef(data(), size());
276 }
277
278 /// Retrieve the number of template arguments in this
279 /// template argument list.
280 unsigned size() const { return NumArguments; }
281
282 /// Retrieve a pointer to the template argument list.
283 const TemplateArgument *data() const {
284 return getTrailingObjects<TemplateArgument>();
285 }
286};
287
288void *allocateDefaultArgStorageChain(const ASTContext &C);
289
290/// Storage for a default argument. This is conceptually either empty, or an
291/// argument value, or a pointer to a previous declaration that had a default
292/// argument.
293///
294/// However, this is complicated by modules: while we require all the default
295/// arguments for a template to be equivalent, there may be more than one, and
296/// we need to track all the originating parameters to determine if the default
297/// argument is visible.
298template<typename ParmDecl, typename ArgType>
300 /// Storage for both the value *and* another parameter from which we inherit
301 /// the default argument. This is used when multiple default arguments for a
302 /// parameter are merged together from different modules.
303 struct Chain {
304 ParmDecl *PrevDeclWithDefaultArg;
305 ArgType Value;
306 };
307 static_assert(sizeof(Chain) == sizeof(void *) * 2,
308 "non-pointer argument type?");
309
310 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
311
312 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
313 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
314 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
315 Parm = Prev;
316 assert(!Parm->getDefaultArgStorage()
317 .ValueOrInherited.template is<ParmDecl *>() &&
318 "should only be one level of indirection");
319 return Parm;
320 }
321
322public:
323 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
324
325 /// Determine whether there is a default argument for this parameter.
326 bool isSet() const { return !ValueOrInherited.isNull(); }
327
328 /// Determine whether the default argument for this parameter was inherited
329 /// from a previous declaration of the same entity.
330 bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
331
332 /// Get the default argument's value. This does not consider whether the
333 /// default argument is visible.
334 ArgType get() const {
335 const DefaultArgStorage *Storage = this;
336 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
337 Storage = &Prev->getDefaultArgStorage();
338 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
339 return C->Value;
340 return Storage->ValueOrInherited.template get<ArgType>();
341 }
342
343 /// Get the parameter from which we inherit the default argument, if any.
344 /// This is the parameter on which the default argument was actually written.
345 const ParmDecl *getInheritedFrom() const {
346 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
347 return D;
348 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
349 return C->PrevDeclWithDefaultArg;
350 return nullptr;
351 }
352
353 /// Set the default argument.
354 void set(ArgType Arg) {
355 assert(!isSet() && "default argument already set");
356 ValueOrInherited = Arg;
357 }
358
359 /// Set that the default argument was inherited from another parameter.
360 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
361 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
362 if (!isSet())
363 ValueOrInherited = InheritedFrom;
364 else if ([[maybe_unused]] auto *D =
365 ValueOrInherited.template dyn_cast<ParmDecl *>()) {
366 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
367 ValueOrInherited =
368 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
369 } else if (auto *Inherited =
370 ValueOrInherited.template dyn_cast<Chain *>()) {
371 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
372 InheritedFrom));
373 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
374 } else
375 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
376 Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
377 }
378
379 /// Remove the default argument, even if it was inherited.
380 void clear() {
381 ValueOrInherited = ArgType();
382 }
383};
384
385//===----------------------------------------------------------------------===//
386// Kinds of Templates
387//===----------------------------------------------------------------------===//
388
389/// \brief The base class of all kinds of template declarations (e.g.,
390/// class, function, etc.).
391///
392/// The TemplateDecl class stores the list of template parameters and a
393/// reference to the templated scoped declaration: the underlying AST node.
394class TemplateDecl : public NamedDecl {
395 void anchor() override;
396
397protected:
398 // Construct a template decl with name, parameters, and templated element.
401
402 // Construct a template decl with the given name and parameters.
403 // Used when there is no templated element (e.g., for tt-params).
405 TemplateParameterList *Params)
406 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
407
408public:
409 friend class ASTDeclReader;
410 friend class ASTDeclWriter;
411
412 /// Get the list of template parameters
414 return TemplateParams;
415 }
416
417 /// \brief Get the total constraint-expression associated with this template,
418 /// including constraint-expressions derived from the requires-clause,
419 /// trailing requires-clause (for functions and methods) and constrained
420 /// template parameters.
422
423 bool hasAssociatedConstraints() const;
424
425 /// Get the underlying, templated declaration.
427
428 // Should a specialization behave like an alias for another type.
429 bool isTypeAlias() const;
430
431 // Implement isa/cast/dyncast/etc.
432 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
433
434 static bool classofKind(Kind K) {
435 return K >= firstTemplate && K <= lastTemplate;
436 }
437
438 SourceRange getSourceRange() const override LLVM_READONLY {
439 return SourceRange(getTemplateParameters()->getTemplateLoc(),
441 }
442
443protected:
446
447public:
449 TemplateParams = TParams;
450 }
451
452 /// Initialize the underlying templated declaration.
453 void init(NamedDecl *NewTemplatedDecl) {
454 if (TemplatedDecl)
455 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
456 else
457 TemplatedDecl = NewTemplatedDecl;
458 }
459};
460
461/// Provides information about a function template specialization,
462/// which is a FunctionDecl that has been explicitly specialization or
463/// instantiated from a function template.
465 : public llvm::FoldingSetNode,
466 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
467 MemberSpecializationInfo *> {
468 /// The function template specialization that this structure describes and a
469 /// flag indicating if the function is a member specialization.
470 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
471
472 /// The function template from which this function template
473 /// specialization was generated.
474 ///
475 /// The two bits contain the top 4 values of TemplateSpecializationKind.
476 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
477
478public:
479 /// The template arguments used to produce the function template
480 /// specialization from the function template.
482
483 /// The template arguments as written in the sources, if provided.
484 /// FIXME: Normally null; tail-allocate this.
486
487 /// The point at which this function template specialization was
488 /// first instantiated.
490
491private:
493 FunctionDecl *FD, FunctionTemplateDecl *Template,
495 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
497 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
498 TemplateArguments(TemplateArgs),
499 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
501 if (MSInfo)
502 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
503 }
504
505 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
506 return Function.getInt();
507 }
508
509public:
511
515 const TemplateArgumentListInfo *TemplateArgsAsWritten,
517
518 /// Retrieve the declaration of the function template specialization.
519 FunctionDecl *getFunction() const { return Function.getPointer(); }
520
521 /// Retrieve the template from which this function was specialized.
522 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
523
524 /// Determine what kind of template specialization this is.
526 return (TemplateSpecializationKind)(Template.getInt() + 1);
527 }
528
531 }
532
533 /// True if this declaration is an explicit specialization,
534 /// explicit instantiation declaration, or explicit instantiation
535 /// definition.
539 }
540
541 /// Set the template specialization kind.
543 assert(TSK != TSK_Undeclared &&
544 "Cannot encode TSK_Undeclared for a function template specialization");
545 Template.setInt(TSK - 1);
546 }
547
548 /// Retrieve the first point of instantiation of this function
549 /// template specialization.
550 ///
551 /// The point of instantiation may be an invalid source location if this
552 /// function has yet to be instantiated.
555 }
556
557 /// Set the (first) point of instantiation of this function template
558 /// specialization.
561 }
562
563 /// Get the specialization info if this function template specialization is
564 /// also a member specialization:
565 ///
566 /// \code
567 /// template<typename> struct A {
568 /// template<typename> void f();
569 /// template<> void f<int>();
570 /// };
571 /// \endcode
572 ///
573 /// Here, A<int>::f<int> is a function template specialization that is
574 /// an explicit specialization of A<int>::f, but it's also a member
575 /// specialization (an implicit instantiation in this case) of A::f<int>.
576 /// Further:
577 ///
578 /// \code
579 /// template<> template<> void A<int>::f<int>() {}
580 /// \endcode
581 ///
582 /// ... declares a function template specialization that is an explicit
583 /// specialization of A<int>::f, and is also an explicit member
584 /// specialization of A::f<int>.
585 ///
586 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
587 /// need not be the same as that returned by getTemplateSpecializationKind(),
588 /// and represents the relationship between the function and the class-scope
589 /// explicit specialization in the original templated class -- whereas our
590 /// TemplateSpecializationKind represents the relationship between the
591 /// function and the function template, and should always be
592 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
594 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
595 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
596 : nullptr;
597 }
598
599 void Profile(llvm::FoldingSetNodeID &ID) {
600 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
601 }
602
603 static void
604 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
605 const ASTContext &Context) {
606 ID.AddInteger(TemplateArgs.size());
607 for (const TemplateArgument &TemplateArg : TemplateArgs)
608 TemplateArg.Profile(ID, Context);
609 }
610};
611
612/// Provides information a specialization of a member of a class
613/// template, which may be a member function, static data member,
614/// member class or member enumeration.
616 // The member declaration from which this member was instantiated, and the
617 // manner in which the instantiation occurred (in the lower two bits).
618 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
619
620 // The point at which this member was first instantiated.
621 SourceLocation PointOfInstantiation;
622
623public:
624 explicit
627 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
628 assert(TSK != TSK_Undeclared &&
629 "Cannot encode undeclared template specializations for members");
630 }
631
632 /// Retrieve the member declaration from which this member was
633 /// instantiated.
634 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
635
636 /// Determine what kind of template specialization this is.
638 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
639 }
640
643 }
644
645 /// Set the template specialization kind.
647 assert(TSK != TSK_Undeclared &&
648 "Cannot encode undeclared template specializations for members");
649 MemberAndTSK.setInt(TSK - 1);
650 }
651
652 /// Retrieve the first point of instantiation of this member.
653 /// If the point of instantiation is an invalid location, then this member
654 /// has not yet been instantiated.
656 return PointOfInstantiation;
657 }
658
659 /// Set the first point of instantiation.
661 PointOfInstantiation = POI;
662 }
663};
664
665/// Provides information about a dependent function-template
666/// specialization declaration.
667///
668/// This is used for function templates explicit specializations declared
669/// within class templates:
670///
671/// \code
672/// template<typename> struct A {
673/// template<typename> void f();
674/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
675/// };
676/// \endcode
677///
678/// As well as dependent friend declarations naming function template
679/// specializations declared within class templates:
680///
681/// \code
682/// template <class T> void foo(T);
683/// template <class T> class A {
684/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
685/// };
686/// \endcode
688 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
689 FunctionTemplateDecl *> {
690 friend TrailingObjects;
691
692 /// The number of candidates for the primary template.
693 unsigned NumCandidates;
694
696 const UnresolvedSetImpl &Candidates,
697 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
698
699public:
700 /// The template arguments as written in the sources, if provided.
702
704 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
705 const TemplateArgumentListInfo *TemplateArgs);
706
707 /// Returns the candidates for the primary function template.
709 return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
710 }
711};
712
713/// Declaration of a redeclarable template.
715 public Redeclarable<RedeclarableTemplateDecl>
716{
718
719 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
720 return getNextRedeclaration();
721 }
722
723 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
724 return getPreviousDecl();
725 }
726
727 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
728 return getMostRecentDecl();
729 }
730
731 void anchor() override;
732protected:
733 template <typename EntryType> struct SpecEntryTraits {
734 using DeclType = EntryType;
735
736 static DeclType *getDecl(EntryType *D) {
737 return D;
738 }
739
741 return D->getTemplateArgs().asArray();
742 }
743 };
744
745 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
746 typename DeclType = typename SETraits::DeclType>
748 : llvm::iterator_adaptor_base<
749 SpecIterator<EntryType, SETraits, DeclType>,
750 typename llvm::FoldingSetVector<EntryType>::iterator,
751 typename std::iterator_traits<typename llvm::FoldingSetVector<
752 EntryType>::iterator>::iterator_category,
753 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
754 SpecIterator() = default;
755 explicit SpecIterator(
756 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
757 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
758
759 DeclType *operator*() const {
760 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
761 }
762
763 DeclType *operator->() const { return **this; }
764 };
765
766 template <typename EntryType>
767 static SpecIterator<EntryType>
768 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
769 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
770 }
771
772 void loadLazySpecializationsImpl() const;
773
774 template <class EntryType, typename ...ProfileArguments>
776 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
777 void *&InsertPos, ProfileArguments &&...ProfileArgs);
778
779 template <class Derived, class EntryType>
780 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
781 EntryType *Entry, void *InsertPos);
782
783 struct CommonBase {
785
786 /// The template from which this was most
787 /// directly instantiated (or null).
788 ///
789 /// The boolean value indicates whether this template
790 /// was explicitly specialized.
791 llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
793
794 /// If non-null, points to an array of specializations (including
795 /// partial specializations) known only by their external declaration IDs.
796 ///
797 /// The first value in the array is the number of specializations/partial
798 /// specializations that follow.
800
801 /// The set of "injected" template arguments used within this
802 /// template.
803 ///
804 /// This pointer refers to the template arguments (there are as
805 /// many template arguments as template parameters) for the
806 /// template, and is allocated lazily, since most templates do not
807 /// require the use of this information.
809 };
810
811 /// Pointer to the common data shared by all declarations of this
812 /// template.
813 mutable CommonBase *Common = nullptr;
814
815 /// Retrieves the "common" pointer shared by all (re-)declarations of
816 /// the same template. Calling this routine may implicitly allocate memory
817 /// for the common pointer.
818 CommonBase *getCommonPtr() const;
819
820 virtual CommonBase *newCommon(ASTContext &C) const = 0;
821
822 // Construct a template decl with name, parameters, and templated element.
826 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
827
828public:
829 friend class ASTDeclReader;
830 friend class ASTDeclWriter;
831 friend class ASTReader;
832 template <class decl_type> friend class RedeclarableTemplate;
833
834 /// Retrieves the canonical declaration of this template.
836 return getFirstDecl();
837 }
839 return getFirstDecl();
840 }
841
842 /// Determines whether this template was a specialization of a
843 /// member template.
844 ///
845 /// In the following example, the function template \c X<int>::f and the
846 /// member template \c X<int>::Inner are member specializations.
847 ///
848 /// \code
849 /// template<typename T>
850 /// struct X {
851 /// template<typename U> void f(T, U);
852 /// template<typename U> struct Inner;
853 /// };
854 ///
855 /// template<> template<typename T>
856 /// void X<int>::f(int, T);
857 /// template<> template<typename T>
858 /// struct X<int>::Inner { /* ... */ };
859 /// \endcode
861 return getCommonPtr()->InstantiatedFromMember.getInt();
862 }
863
864 /// Note that this member template is a specialization.
866 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
867 "Only member templates can be member template specializations");
868 getCommonPtr()->InstantiatedFromMember.setInt(true);
869 }
870
871 /// Retrieve the member template from which this template was
872 /// instantiated, or nullptr if this template was not instantiated from a
873 /// member template.
874 ///
875 /// A template is instantiated from a member template when the member
876 /// template itself is part of a class template (or member thereof). For
877 /// example, given
878 ///
879 /// \code
880 /// template<typename T>
881 /// struct X {
882 /// template<typename U> void f(T, U);
883 /// };
884 ///
885 /// void test(X<int> x) {
886 /// x.f(1, 'a');
887 /// };
888 /// \endcode
889 ///
890 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
891 /// template
892 ///
893 /// \code
894 /// template<typename U> void X<int>::f(int, U);
895 /// \endcode
896 ///
897 /// which was itself created during the instantiation of \c X<int>. Calling
898 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
899 /// retrieve the FunctionTemplateDecl for the original template \c f within
900 /// the class template \c X<T>, i.e.,
901 ///
902 /// \code
903 /// template<typename T>
904 /// template<typename U>
905 /// void X<T>::f(T, U);
906 /// \endcode
908 return getCommonPtr()->InstantiatedFromMember.getPointer();
909 }
910
912 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
913 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
914 }
915
916 /// Retrieve the "injected" template arguments that correspond to the
917 /// template parameters of this template.
918 ///
919 /// Although the C++ standard has no notion of the "injected" template
920 /// arguments for a template, the notion is convenient when
921 /// we need to perform substitutions inside the definition of a template.
923
925 using redecl_iterator = redeclarable_base::redecl_iterator;
926
933
934 // Implement isa/cast/dyncast/etc.
935 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
936
937 static bool classofKind(Kind K) {
938 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
939 }
940};
941
942template <> struct RedeclarableTemplateDecl::
943SpecEntryTraits<FunctionTemplateSpecializationInfo> {
945
947 return I->getFunction();
948 }
949
952 return I->TemplateArguments->asArray();
953 }
954};
955
956/// Declaration of a template function.
958protected:
959 friend class FunctionDecl;
960
961 /// Data that is common to all of the declarations of a given
962 /// function template.
964 /// The function template specializations for this function
965 /// template, including explicit specializations and instantiations.
966 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
967
968 Common() = default;
969 };
970
974 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
975 Decl) {}
976
977 CommonBase *newCommon(ASTContext &C) const override;
978
980 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
981 }
982
983 /// Retrieve the set of function template specializations of this
984 /// function template.
985 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
986 getSpecializations() const;
987
988 /// Add a specialization of this function template.
989 ///
990 /// \param InsertPos Insert position in the FoldingSetVector, must have been
991 /// retrieved by an earlier call to findSpecialization().
993 void *InsertPos);
994
995public:
996 friend class ASTDeclReader;
997 friend class ASTDeclWriter;
998
999 /// Load any lazily-loaded specializations from the external source.
1000 void LoadLazySpecializations() const;
1001
1002 /// Get the underlying function declaration of the template.
1004 return static_cast<FunctionDecl *>(TemplatedDecl);
1005 }
1006
1007 /// Returns whether this template declaration defines the primary
1008 /// pattern.
1011 }
1012
1013 /// Return the specialization with the provided arguments if it exists,
1014 /// otherwise return the insertion point.
1016 void *&InsertPos);
1017
1019 return cast<FunctionTemplateDecl>(
1021 }
1023 return cast<FunctionTemplateDecl>(
1025 }
1026
1027 /// Retrieve the previous declaration of this function template, or
1028 /// nullptr if no such declaration exists.
1030 return cast_or_null<FunctionTemplateDecl>(
1031 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1032 }
1034 return cast_or_null<FunctionTemplateDecl>(
1035 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1036 }
1037
1039 return cast<FunctionTemplateDecl>(
1040 static_cast<RedeclarableTemplateDecl *>(this)
1041 ->getMostRecentDecl());
1042 }
1044 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1045 }
1046
1048 return cast_or_null<FunctionTemplateDecl>(
1050 }
1051
1053 using spec_range = llvm::iterator_range<spec_iterator>;
1054
1056 return spec_range(spec_begin(), spec_end());
1057 }
1058
1060 return makeSpecIterator(getSpecializations(), false);
1061 }
1062
1064 return makeSpecIterator(getSpecializations(), true);
1065 }
1066
1067 /// Return whether this function template is an abbreviated function template,
1068 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1069 bool isAbbreviated() const {
1070 // Since the invented template parameters generated from 'auto' parameters
1071 // are either appended to the end of the explicit template parameter list or
1072 // form a new template parameter list, we can simply observe the last
1073 // parameter to determine if such a thing happened.
1075 return TPL->getParam(TPL->size() - 1)->isImplicit();
1076 }
1077
1078 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1080
1081 /// Create a function template node.
1084 DeclarationName Name,
1085 TemplateParameterList *Params,
1086 NamedDecl *Decl);
1087
1088 /// Create an empty function template node.
1091
1092 // Implement isa/cast/dyncast support
1093 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1094 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1095};
1096
1097//===----------------------------------------------------------------------===//
1098// Kinds of Template Parameters
1099//===----------------------------------------------------------------------===//
1100
1101/// Defines the position of a template parameter within a template
1102/// parameter list.
1103///
1104/// Because template parameter can be listed
1105/// sequentially for out-of-line template members, each template parameter is
1106/// given a Depth - the nesting of template parameter scopes - and a Position -
1107/// the occurrence within the parameter list.
1108/// This class is inheritedly privately by different kinds of template
1109/// parameters and is not part of the Decl hierarchy. Just a facility.
1111protected:
1112 enum { DepthWidth = 20, PositionWidth = 12 };
1113 unsigned Depth : DepthWidth;
1115
1116 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1117 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1118
1119 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1120 // The input may fill maximum values to show that it is invalid.
1121 // Add one here to convert it to zero.
1122 assert((D + 1) <= MaxDepth &&
1123 "The depth of template parmeter position is more than 2^20!");
1124 assert((P + 1) <= MaxPosition &&
1125 "The position of template parmeter position is more than 2^12!");
1126 }
1127
1128public:
1130
1131 /// Get the nesting depth of the template parameter.
1132 unsigned getDepth() const { return Depth; }
1133 void setDepth(unsigned D) {
1134 assert((D + 1) <= MaxDepth &&
1135 "The depth of template parmeter position is more than 2^20!");
1136 Depth = D;
1137 }
1138
1139 /// Get the position of the template parameter within its parameter list.
1140 unsigned getPosition() const { return Position; }
1141 void setPosition(unsigned P) {
1142 assert((P + 1) <= MaxPosition &&
1143 "The position of template parmeter position is more than 2^12!");
1144 Position = P;
1145 }
1146
1147 /// Get the index of the template parameter within its parameter list.
1148 unsigned getIndex() const { return Position; }
1149};
1150
1151/// Declaration of a template type parameter.
1152///
1153/// For example, "T" in
1154/// \code
1155/// template<typename T> class vector;
1156/// \endcode
1157class TemplateTypeParmDecl final : public TypeDecl,
1158 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1159 /// Sema creates these on the stack during auto type deduction.
1160 friend class Sema;
1161 friend TrailingObjects;
1162 friend class ASTDeclReader;
1163
1164 /// Whether this template type parameter was declaration with
1165 /// the 'typename' keyword.
1166 ///
1167 /// If false, it was declared with the 'class' keyword.
1168 bool Typename : 1;
1169
1170 /// Whether this template type parameter has a type-constraint construct.
1171 bool HasTypeConstraint : 1;
1172
1173 /// Whether the type constraint has been initialized. This can be false if the
1174 /// constraint was not initialized yet or if there was an error forming the
1175 /// type constraint.
1176 bool TypeConstraintInitialized : 1;
1177
1178 /// Whether this type template parameter is an "expanded"
1179 /// parameter pack, meaning that its type is a pack expansion and we
1180 /// already know the set of types that expansion expands to.
1181 bool ExpandedParameterPack : 1;
1182
1183 /// The number of type parameters in an expanded parameter pack.
1184 unsigned NumExpanded = 0;
1185
1186 /// The default template argument, if any.
1187 using DefArgStorage =
1189 DefArgStorage DefaultArgument;
1190
1192 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1193 bool HasTypeConstraint,
1194 std::optional<unsigned> NumExpanded)
1195 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1196 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1197 ExpandedParameterPack(NumExpanded),
1198 NumExpanded(NumExpanded.value_or(0)) {}
1199
1200public:
1201 static TemplateTypeParmDecl *
1202 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1203 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1204 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1205 std::optional<unsigned> NumExpanded = std::nullopt);
1210 bool HasTypeConstraint);
1211
1212 /// Whether this template type parameter was declared with
1213 /// the 'typename' keyword.
1214 ///
1215 /// If not, it was either declared with the 'class' keyword or with a
1216 /// type-constraint (see hasTypeConstraint()).
1218 return Typename && !HasTypeConstraint;
1219 }
1220
1221 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1222
1223 /// Determine whether this template parameter has a default
1224 /// argument.
1225 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1226
1227 /// Retrieve the default argument, if any.
1229 return DefaultArgument.get()->getType();
1230 }
1231
1232 /// Retrieves the default argument's source information, if any.
1234 return DefaultArgument.get();
1235 }
1236
1237 /// Retrieves the location of the default argument declaration.
1239
1240 /// Determines whether the default argument was inherited
1241 /// from a previous declaration of this template.
1243 return DefaultArgument.isInherited();
1244 }
1245
1246 /// Set the default argument for this template parameter.
1248 DefaultArgument.set(DefArg);
1249 }
1250
1251 /// Set that this default argument was inherited from another
1252 /// parameter.
1254 TemplateTypeParmDecl *Prev) {
1255 DefaultArgument.setInherited(C, Prev);
1256 }
1257
1258 /// Removes the default argument of this template parameter.
1260 DefaultArgument.clear();
1261 }
1262
1263 /// Set whether this template type parameter was declared with
1264 /// the 'typename' or 'class' keyword.
1265 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1266
1267 /// Retrieve the depth of the template parameter.
1268 unsigned getDepth() const;
1269
1270 /// Retrieve the index of the template parameter.
1271 unsigned getIndex() const;
1272
1273 /// Returns whether this is a parameter pack.
1274 bool isParameterPack() const;
1275
1276 /// Whether this parameter pack is a pack expansion.
1277 ///
1278 /// A template type template parameter pack can be a pack expansion if its
1279 /// type-constraint contains an unexpanded parameter pack.
1280 bool isPackExpansion() const {
1281 if (!isParameterPack())
1282 return false;
1283 if (const TypeConstraint *TC = getTypeConstraint())
1284 if (TC->hasExplicitTemplateArgs())
1285 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1286 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1287 return true;
1288 return false;
1289 }
1290
1291 /// Whether this parameter is a template type parameter pack that has a known
1292 /// list of different type-constraints at different positions.
1293 ///
1294 /// A parameter pack is an expanded parameter pack when the original
1295 /// parameter pack's type-constraint was itself a pack expansion, and that
1296 /// expansion has already been expanded. For example, given:
1297 ///
1298 /// \code
1299 /// template<typename ...Types>
1300 /// struct X {
1301 /// template<convertible_to<Types> ...Convertibles>
1302 /// struct Y { /* ... */ };
1303 /// };
1304 /// \endcode
1305 ///
1306 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1307 /// its type-constraint. When \c Types is supplied with template arguments by
1308 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1309 /// expanded parameter pack. For example, instantiating
1310 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1311 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1312 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1313
1314 /// Retrieves the number of parameters in an expanded parameter pack.
1315 unsigned getNumExpansionParameters() const {
1316 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1317 return NumExpanded;
1318 }
1319
1320 /// Returns the type constraint associated with this template parameter (if
1321 /// any).
1323 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1324 nullptr;
1325 }
1326
1328 Expr *ImmediatelyDeclaredConstraint);
1329
1330 /// Determine whether this template parameter has a type-constraint.
1331 bool hasTypeConstraint() const {
1332 return HasTypeConstraint;
1333 }
1334
1335 /// \brief Get the associated-constraints of this template parameter.
1336 /// This will either be the immediately-introduced constraint or empty.
1337 ///
1338 /// Use this instead of getTypeConstraint for concepts APIs that
1339 /// accept an ArrayRef of constraint expressions.
1341 if (HasTypeConstraint)
1342 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1343 }
1344
1345 SourceRange getSourceRange() const override LLVM_READONLY;
1346
1347 // Implement isa/cast/dyncast/etc.
1348 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1349 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1350};
1351
1352/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1353/// e.g., "Size" in
1354/// @code
1355/// template<int Size> class array { };
1356/// @endcode
1358 : public DeclaratorDecl,
1359 protected TemplateParmPosition,
1360 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1361 std::pair<QualType, TypeSourceInfo *>,
1362 Expr *> {
1363 friend class ASTDeclReader;
1364 friend TrailingObjects;
1365
1366 /// The default template argument, if any, and whether or not
1367 /// it was inherited.
1369 DefArgStorage DefaultArgument;
1370
1371 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1372 // down here to save memory.
1373
1374 /// Whether this non-type template parameter is a parameter pack.
1375 bool ParameterPack;
1376
1377 /// Whether this non-type template parameter is an "expanded"
1378 /// parameter pack, meaning that its type is a pack expansion and we
1379 /// already know the set of types that expansion expands to.
1380 bool ExpandedParameterPack = false;
1381
1382 /// The number of types in an expanded parameter pack.
1383 unsigned NumExpandedTypes = 0;
1384
1385 size_t numTrailingObjects(
1386 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1387 return NumExpandedTypes;
1388 }
1389
1391 SourceLocation IdLoc, unsigned D, unsigned P,
1392 const IdentifierInfo *Id, QualType T,
1393 bool ParameterPack, TypeSourceInfo *TInfo)
1394 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1395 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1396
1397 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1398 SourceLocation IdLoc, unsigned D, unsigned P,
1399 const IdentifierInfo *Id, QualType T,
1400 TypeSourceInfo *TInfo,
1401 ArrayRef<QualType> ExpandedTypes,
1402 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1403
1404public:
1405 static NonTypeTemplateParmDecl *
1406 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1407 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1408 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1409
1410 static NonTypeTemplateParmDecl *
1411 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1412 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1413 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1414 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1415
1416 static NonTypeTemplateParmDecl *
1417 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1418 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1419 GlobalDeclID ID,
1420 unsigned NumExpandedTypes,
1421 bool HasTypeConstraint);
1422
1428
1429 SourceRange getSourceRange() const override LLVM_READONLY;
1430
1431 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1432
1433 /// Determine whether this template parameter has a default
1434 /// argument.
1435 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1436
1437 /// Retrieve the default argument, if any.
1438 Expr *getDefaultArgument() const { return DefaultArgument.get(); }
1439
1440 /// Retrieve the location of the default argument, if any.
1442
1443 /// Determines whether the default argument was inherited
1444 /// from a previous declaration of this template.
1446 return DefaultArgument.isInherited();
1447 }
1448
1449 /// Set the default argument for this template parameter, and
1450 /// whether that default argument was inherited from another
1451 /// declaration.
1452 void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
1455 DefaultArgument.setInherited(C, Parm);
1456 }
1457
1458 /// Removes the default argument of this template parameter.
1459 void removeDefaultArgument() { DefaultArgument.clear(); }
1460
1461 /// Whether this parameter is a non-type template parameter pack.
1462 ///
1463 /// If the parameter is a parameter pack, the type may be a
1464 /// \c PackExpansionType. In the following example, the \c Dims parameter
1465 /// is a parameter pack (whose type is 'unsigned').
1466 ///
1467 /// \code
1468 /// template<typename T, unsigned ...Dims> struct multi_array;
1469 /// \endcode
1470 bool isParameterPack() const { return ParameterPack; }
1471
1472 /// Whether this parameter pack is a pack expansion.
1473 ///
1474 /// A non-type template parameter pack is a pack expansion if its type
1475 /// contains an unexpanded parameter pack. In this case, we will have
1476 /// built a PackExpansionType wrapping the type.
1477 bool isPackExpansion() const {
1478 return ParameterPack && getType()->getAs<PackExpansionType>();
1479 }
1480
1481 /// Whether this parameter is a non-type template parameter pack
1482 /// that has a known list of different types at different positions.
1483 ///
1484 /// A parameter pack is an expanded parameter pack when the original
1485 /// parameter pack's type was itself a pack expansion, and that expansion
1486 /// has already been expanded. For example, given:
1487 ///
1488 /// \code
1489 /// template<typename ...Types>
1490 /// struct X {
1491 /// template<Types ...Values>
1492 /// struct Y { /* ... */ };
1493 /// };
1494 /// \endcode
1495 ///
1496 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1497 /// which expands \c Types. When \c Types is supplied with template arguments
1498 /// by instantiating \c X, the instantiation of \c Values becomes an
1499 /// expanded parameter pack. For example, instantiating
1500 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1501 /// pack with expansion types \c int and \c unsigned int.
1502 ///
1503 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1504 /// return the expansion types.
1505 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1506
1507 /// Retrieves the number of expansion types in an expanded parameter
1508 /// pack.
1509 unsigned getNumExpansionTypes() const {
1510 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1511 return NumExpandedTypes;
1512 }
1513
1514 /// Retrieve a particular expansion type within an expanded parameter
1515 /// pack.
1516 QualType getExpansionType(unsigned I) const {
1517 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1518 auto TypesAndInfos =
1519 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1520 return TypesAndInfos[I].first;
1521 }
1522
1523 /// Retrieve a particular expansion type source info within an
1524 /// expanded parameter pack.
1526 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1527 auto TypesAndInfos =
1528 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1529 return TypesAndInfos[I].second;
1530 }
1531
1532 /// Return the constraint introduced by the placeholder type of this non-type
1533 /// template parameter (if any).
1535 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1536 nullptr;
1537 }
1538
1540 *getTrailingObjects<Expr *>() = E;
1541 }
1542
1543 /// Determine whether this non-type template parameter's type has a
1544 /// placeholder with a type-constraint.
1546 auto *AT = getType()->getContainedAutoType();
1547 return AT && AT->isConstrained();
1548 }
1549
1550 /// \brief Get the associated-constraints of this template parameter.
1551 /// This will either be a vector of size 1 containing the immediately-declared
1552 /// constraint introduced by the placeholder type, or an empty vector.
1553 ///
1554 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1555 /// concepts APIs that accept an ArrayRef of constraint expressions.
1558 AC.push_back(E);
1559 }
1560
1561 // Implement isa/cast/dyncast/etc.
1562 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1563 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1564};
1565
1566/// TemplateTemplateParmDecl - Declares a template template parameter,
1567/// e.g., "T" in
1568/// @code
1569/// template <template <typename> class T> class container { };
1570/// @endcode
1571/// A template template parameter is a TemplateDecl because it defines the
1572/// name of a template and the template parameters allowable for substitution.
1574 : public TemplateDecl,
1575 protected TemplateParmPosition,
1576 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1577 TemplateParameterList *> {
1578 /// The default template argument, if any.
1579 using DefArgStorage =
1581 DefArgStorage DefaultArgument;
1582
1583 /// Whether this template template parameter was declaration with
1584 /// the 'typename' keyword.
1585 ///
1586 /// If false, it was declared with the 'class' keyword.
1587 LLVM_PREFERRED_TYPE(bool)
1588 unsigned Typename : 1;
1589
1590 /// Whether this parameter is a parameter pack.
1591 LLVM_PREFERRED_TYPE(bool)
1592 unsigned ParameterPack : 1;
1593
1594 /// Whether this template template parameter is an "expanded"
1595 /// parameter pack, meaning that it is a pack expansion and we
1596 /// already know the set of template parameters that expansion expands to.
1597 LLVM_PREFERRED_TYPE(bool)
1598 unsigned ExpandedParameterPack : 1;
1599
1600 /// The number of parameters in an expanded parameter pack.
1601 unsigned NumExpandedParams = 0;
1602
1604 unsigned P, bool ParameterPack, IdentifierInfo *Id,
1605 bool Typename, TemplateParameterList *Params)
1606 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1608 ParameterPack(ParameterPack), ExpandedParameterPack(false) {}
1609
1611 unsigned P, IdentifierInfo *Id, bool Typename,
1612 TemplateParameterList *Params,
1614
1615 void anchor() override;
1616
1617public:
1618 friend class ASTDeclReader;
1619 friend class ASTDeclWriter;
1621
1623 SourceLocation L, unsigned D,
1624 unsigned P, bool ParameterPack,
1625 IdentifierInfo *Id, bool Typename,
1626 TemplateParameterList *Params);
1628 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
1629 unsigned P, IdentifierInfo *Id, bool Typename,
1630 TemplateParameterList *Params,
1632
1636 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1637
1643
1644 /// Whether this template template parameter was declared with
1645 /// the 'typename' keyword.
1646 bool wasDeclaredWithTypename() const { return Typename; }
1647
1648 /// Set whether this template template parameter was declared with
1649 /// the 'typename' or 'class' keyword.
1650 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1651
1652 /// Whether this template template parameter is a template
1653 /// parameter pack.
1654 ///
1655 /// \code
1656 /// template<template <class T> ...MetaFunctions> struct Apply;
1657 /// \endcode
1658 bool isParameterPack() const { return ParameterPack; }
1659
1660 /// Whether this parameter pack is a pack expansion.
1661 ///
1662 /// A template template parameter pack is a pack expansion if its template
1663 /// parameter list contains an unexpanded parameter pack.
1664 bool isPackExpansion() const {
1665 return ParameterPack &&
1667 }
1668
1669 /// Whether this parameter is a template template parameter pack that
1670 /// has a known list of different template parameter lists at different
1671 /// positions.
1672 ///
1673 /// A parameter pack is an expanded parameter pack when the original parameter
1674 /// pack's template parameter list was itself a pack expansion, and that
1675 /// expansion has already been expanded. For exampe, given:
1676 ///
1677 /// \code
1678 /// template<typename...Types> struct Outer {
1679 /// template<template<Types> class...Templates> struct Inner;
1680 /// };
1681 /// \endcode
1682 ///
1683 /// The parameter pack \c Templates is a pack expansion, which expands the
1684 /// pack \c Types. When \c Types is supplied with template arguments by
1685 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1686 /// parameter pack.
1687 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1688
1689 /// Retrieves the number of expansion template parameters in
1690 /// an expanded parameter pack.
1692 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1693 return NumExpandedParams;
1694 }
1695
1696 /// Retrieve a particular expansion type within an expanded parameter
1697 /// pack.
1699 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1700 return getTrailingObjects<TemplateParameterList *>()[I];
1701 }
1702
1703 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1704
1705 /// Determine whether this template parameter has a default
1706 /// argument.
1707 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1708
1709 /// Retrieve the default argument, if any.
1711 static const TemplateArgumentLoc NoneLoc;
1712 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1713 }
1714
1715 /// Retrieve the location of the default argument, if any.
1717
1718 /// Determines whether the default argument was inherited
1719 /// from a previous declaration of this template.
1721 return DefaultArgument.isInherited();
1722 }
1723
1724 /// Set the default argument for this template parameter, and
1725 /// whether that default argument was inherited from another
1726 /// declaration.
1727 void setDefaultArgument(const ASTContext &C,
1728 const TemplateArgumentLoc &DefArg);
1731 DefaultArgument.setInherited(C, Prev);
1732 }
1733
1734 /// Removes the default argument of this template parameter.
1735 void removeDefaultArgument() { DefaultArgument.clear(); }
1736
1737 SourceRange getSourceRange() const override LLVM_READONLY {
1741 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1742 }
1743
1744 // Implement isa/cast/dyncast/etc.
1745 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1746 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1747};
1748
1749/// Represents the builtin template declaration which is used to
1750/// implement __make_integer_seq and other builtin templates. It serves
1751/// no real purpose beyond existing as a place to hold template parameters.
1754
1757
1758 void anchor() override;
1759
1760public:
1761 // Implement isa/cast/dyncast support
1762 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1763 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1764
1766 DeclarationName Name,
1767 BuiltinTemplateKind BTK) {
1768 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1769 }
1770
1771 SourceRange getSourceRange() const override LLVM_READONLY {
1772 return {};
1773 }
1774
1776};
1777
1778/// Provides information about an explicit instantiation of a variable or class
1779/// template.
1781 /// The template arguments as written..
1783
1784 /// The location of the extern keyword.
1786
1787 /// The location of the template keyword.
1789
1791};
1792
1794 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1796
1797/// Represents a class template specialization, which refers to
1798/// a class template with a given set of template arguments.
1799///
1800/// Class template specializations represent both explicit
1801/// specialization of class templates, as in the example below, and
1802/// implicit instantiations of class templates.
1803///
1804/// \code
1805/// template<typename T> class array;
1806///
1807/// template<>
1808/// class array<bool> { }; // class template specialization array<bool>
1809/// \endcode
1811 public llvm::FoldingSetNode {
1812 /// Structure that stores information about a class template
1813 /// specialization that was instantiated from a class template partial
1814 /// specialization.
1815 struct SpecializedPartialSpecialization {
1816 /// The class template partial specialization from which this
1817 /// class template specialization was instantiated.
1818 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1819
1820 /// The template argument list deduced for the class template
1821 /// partial specialization itself.
1822 const TemplateArgumentList *TemplateArgs;
1823 };
1824
1825 /// The template that this specialization specializes
1826 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1827 SpecializedTemplate;
1828
1829 /// Further info for explicit template specialization/instantiation.
1830 /// Does not apply to implicit specializations.
1831 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1832
1833 /// The template arguments used to describe this specialization.
1834 const TemplateArgumentList *TemplateArgs;
1835
1836 /// The point where this template was instantiated (if any)
1837 SourceLocation PointOfInstantiation;
1838
1839 /// The kind of specialization this declaration refers to.
1840 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1841 unsigned SpecializationKind : 3;
1842
1843protected:
1845 DeclContext *DC, SourceLocation StartLoc,
1846 SourceLocation IdLoc,
1847 ClassTemplateDecl *SpecializedTemplate,
1850
1852
1853public:
1854 friend class ASTDeclReader;
1855 friend class ASTDeclWriter;
1856
1858 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1859 SourceLocation StartLoc, SourceLocation IdLoc,
1860 ClassTemplateDecl *SpecializedTemplate,
1865
1866 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1867 bool Qualified) const override;
1868
1869 // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1870 // different "most recent" declaration from this function for the same
1871 // declaration, because we don't override getMostRecentDeclImpl(). But
1872 // it's not clear that we should override that, because the most recent
1873 // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1875 return cast<ClassTemplateSpecializationDecl>(
1877 }
1878
1879 /// Retrieve the template that this specialization specializes.
1881
1882 /// Retrieve the template arguments of the class template
1883 /// specialization.
1885 return *TemplateArgs;
1886 }
1887
1889 TemplateArgs = Args;
1890 }
1891
1892 /// Determine the kind of specialization that this
1893 /// declaration represents.
1895 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1896 }
1897
1900 }
1901
1902 /// Is this an explicit specialization at class scope (within the class that
1903 /// owns the primary template)? For example:
1904 ///
1905 /// \code
1906 /// template<typename T> struct Outer {
1907 /// template<typename U> struct Inner;
1908 /// template<> struct Inner; // class-scope explicit specialization
1909 /// };
1910 /// \endcode
1912 return isExplicitSpecialization() &&
1913 isa<CXXRecordDecl>(getLexicalDeclContext());
1914 }
1915
1916 /// True if this declaration is an explicit specialization,
1917 /// explicit instantiation declaration, or explicit instantiation
1918 /// definition.
1922 }
1923
1925 SpecializedTemplate = Specialized;
1926 }
1927
1929 SpecializationKind = TSK;
1930 }
1931
1932 /// Get the point of instantiation (if any), or null if none.
1934 return PointOfInstantiation;
1935 }
1936
1938 assert(Loc.isValid() && "point of instantiation must be valid!");
1939 PointOfInstantiation = Loc;
1940 }
1941
1942 /// If this class template specialization is an instantiation of
1943 /// a template (rather than an explicit specialization), return the
1944 /// class template or class template partial specialization from which it
1945 /// was instantiated.
1946 llvm::PointerUnion<ClassTemplateDecl *,
1950 return llvm::PointerUnion<ClassTemplateDecl *,
1952
1954 }
1955
1956 /// Retrieve the class template or class template partial
1957 /// specialization which was specialized by this.
1958 llvm::PointerUnion<ClassTemplateDecl *,
1961 if (const auto *PartialSpec =
1962 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1963 return PartialSpec->PartialSpecialization;
1964
1965 return SpecializedTemplate.get<ClassTemplateDecl*>();
1966 }
1967
1968 /// Retrieve the set of template arguments that should be used
1969 /// to instantiate members of the class template or class template partial
1970 /// specialization from which this class template specialization was
1971 /// instantiated.
1972 ///
1973 /// \returns For a class template specialization instantiated from the primary
1974 /// template, this function will return the same template arguments as
1975 /// getTemplateArgs(). For a class template specialization instantiated from
1976 /// a class template partial specialization, this function will return the
1977 /// deduced template arguments for the class template partial specialization
1978 /// itself.
1980 if (const auto *PartialSpec =
1981 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1982 return *PartialSpec->TemplateArgs;
1983
1984 return getTemplateArgs();
1985 }
1986
1987 /// Note that this class template specialization is actually an
1988 /// instantiation of the given class template partial specialization whose
1989 /// template arguments have been deduced.
1991 const TemplateArgumentList *TemplateArgs) {
1992 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
1993 "Already set to a class template partial specialization!");
1994 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
1995 PS->PartialSpecialization = PartialSpec;
1996 PS->TemplateArgs = TemplateArgs;
1997 SpecializedTemplate = PS;
1998 }
1999
2000 /// Note that this class template specialization is an instantiation
2001 /// of the given class template.
2003 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
2004 "Previously set to a class template partial specialization!");
2005 SpecializedTemplate = TemplDecl;
2006 }
2007
2008 /// Retrieve the template argument list as written in the sources,
2009 /// if any.
2011 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2012 return Info->TemplateArgsAsWritten;
2013 return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
2014 }
2015
2016 /// Set the template argument list as written in the sources.
2017 void
2019 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2020 Info->TemplateArgsAsWritten = ArgsWritten;
2021 else
2022 ExplicitInfo = ArgsWritten;
2023 }
2024
2025 /// Set the template argument list as written in the sources.
2029 }
2030
2031 /// Gets the location of the extern keyword, if present.
2033 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2034 return Info->ExternKeywordLoc;
2035 return SourceLocation();
2036 }
2037
2038 /// Sets the location of the extern keyword.
2040
2041 /// Gets the location of the template keyword, if present.
2043 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2044 return Info->TemplateKeywordLoc;
2045 return SourceLocation();
2046 }
2047
2048 /// Sets the location of the template keyword.
2050
2051 SourceRange getSourceRange() const override LLVM_READONLY;
2052
2053 void Profile(llvm::FoldingSetNodeID &ID) const {
2054 Profile(ID, TemplateArgs->asArray(), getASTContext());
2055 }
2056
2057 static void
2058 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2059 const ASTContext &Context) {
2060 ID.AddInteger(TemplateArgs.size());
2061 for (const TemplateArgument &TemplateArg : TemplateArgs)
2062 TemplateArg.Profile(ID, Context);
2063 }
2064
2065 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2066
2067 static bool classofKind(Kind K) {
2068 return K >= firstClassTemplateSpecialization &&
2069 K <= lastClassTemplateSpecialization;
2070 }
2071};
2072
2075 /// The list of template parameters
2076 TemplateParameterList* TemplateParams = nullptr;
2077
2078 /// The class template partial specialization from which this
2079 /// class template partial specialization was instantiated.
2080 ///
2081 /// The boolean value will be true to indicate that this class template
2082 /// partial specialization was specialized at this level.
2083 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2084 InstantiatedFromMember;
2085
2087 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2089 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2091
2093 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2094 InstantiatedFromMember(nullptr, false) {}
2095
2096 void anchor() override;
2097
2098public:
2099 friend class ASTDeclReader;
2100 friend class ASTDeclWriter;
2101
2103 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2104 SourceLocation StartLoc, SourceLocation IdLoc,
2105 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2106 ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
2108
2111
2113 return cast<ClassTemplatePartialSpecializationDecl>(
2114 static_cast<ClassTemplateSpecializationDecl *>(
2115 this)->getMostRecentDecl());
2116 }
2117
2118 /// Get the list of template parameters
2120 return TemplateParams;
2121 }
2122
2123 /// \brief All associated constraints of this partial specialization,
2124 /// including the requires clause and any constraints derived from
2125 /// constrained-parameters.
2126 ///
2127 /// The constraints in the resulting list are to be treated as if in a
2128 /// conjunction ("and").
2130 TemplateParams->getAssociatedConstraints(AC);
2131 }
2132
2134 return TemplateParams->hasAssociatedConstraints();
2135 }
2136
2137 /// Retrieve the member class template partial specialization from
2138 /// which this particular class template partial specialization was
2139 /// instantiated.
2140 ///
2141 /// \code
2142 /// template<typename T>
2143 /// struct Outer {
2144 /// template<typename U> struct Inner;
2145 /// template<typename U> struct Inner<U*> { }; // #1
2146 /// };
2147 ///
2148 /// Outer<float>::Inner<int*> ii;
2149 /// \endcode
2150 ///
2151 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2152 /// end up instantiating the partial specialization
2153 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2154 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2155 /// \c Outer<float>::Inner<U*>, this function would return
2156 /// \c Outer<T>::Inner<U*>.
2158 const auto *First =
2159 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2160 return First->InstantiatedFromMember.getPointer();
2161 }
2165 }
2166
2169 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2170 First->InstantiatedFromMember.setPointer(PartialSpec);
2171 }
2172
2173 /// Determines whether this class template partial specialization
2174 /// template was a specialization of a member partial specialization.
2175 ///
2176 /// In the following example, the member template partial specialization
2177 /// \c X<int>::Inner<T*> is a member specialization.
2178 ///
2179 /// \code
2180 /// template<typename T>
2181 /// struct X {
2182 /// template<typename U> struct Inner;
2183 /// template<typename U> struct Inner<U*>;
2184 /// };
2185 ///
2186 /// template<> template<typename T>
2187 /// struct X<int>::Inner<T*> { /* ... */ };
2188 /// \endcode
2190 const auto *First =
2191 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2192 return First->InstantiatedFromMember.getInt();
2193 }
2194
2195 /// Note that this member template is a specialization.
2197 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2198 assert(First->InstantiatedFromMember.getPointer() &&
2199 "Only member templates can be member template specializations");
2200 return First->InstantiatedFromMember.setInt(true);
2201 }
2202
2203 /// Retrieves the injected specialization type for this partial
2204 /// specialization. This is not the same as the type-decl-type for
2205 /// this partial specialization, which is an InjectedClassNameType.
2207 assert(getTypeForDecl() && "partial specialization has no type set!");
2208 return cast<InjectedClassNameType>(getTypeForDecl())
2209 ->getInjectedSpecializationType();
2210 }
2211
2212 SourceRange getSourceRange() const override LLVM_READONLY;
2213
2214 void Profile(llvm::FoldingSetNodeID &ID) const {
2216 getASTContext());
2217 }
2218
2219 static void
2220 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2221 TemplateParameterList *TPL, const ASTContext &Context);
2222
2223 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2224
2225 static bool classofKind(Kind K) {
2226 return K == ClassTemplatePartialSpecialization;
2227 }
2228};
2229
2230/// Declaration of a class template.
2232protected:
2233 /// Data that is common to all of the declarations of a given
2234 /// class template.
2236 /// The class template specializations for this class
2237 /// template, including explicit specializations and instantiations.
2238 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2239
2240 /// The class template partial specializations for this class
2241 /// template.
2242 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2244
2245 /// The injected-class-name type for this class template.
2247
2248 Common() = default;
2249 };
2250
2251 /// Retrieve the set of specializations of this class template.
2252 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2253 getSpecializations() const;
2254
2255 /// Retrieve the set of partial specializations of this class
2256 /// template.
2257 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2259
2262 NamedDecl *Decl)
2263 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2264
2265 CommonBase *newCommon(ASTContext &C) const override;
2266
2268 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2269 }
2270
2273 }
2274
2275public:
2276
2277 friend class ASTDeclReader;
2278 friend class ASTDeclWriter;
2280
2281 /// Load any lazily-loaded specializations from the external source.
2282 void LoadLazySpecializations() const;
2283
2284 /// Get the underlying class declarations of the template.
2286 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2287 }
2288
2289 /// Returns whether this template declaration defines the primary
2290 /// class pattern.
2293 }
2294
2295 /// \brief Create a class template node.
2298 DeclarationName Name,
2299 TemplateParameterList *Params,
2300 NamedDecl *Decl);
2301
2302 /// Create an empty class template node.
2304
2305 /// Return the specialization with the provided arguments if it exists,
2306 /// otherwise return the insertion point.
2308 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2309
2310 /// Insert the specified specialization knowing that it is not already
2311 /// in. InsertPos must be obtained from findSpecialization.
2312 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2313
2315 return cast<ClassTemplateDecl>(
2317 }
2319 return cast<ClassTemplateDecl>(
2321 }
2322
2323 /// Retrieve the previous declaration of this class template, or
2324 /// nullptr if no such declaration exists.
2326 return cast_or_null<ClassTemplateDecl>(
2327 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2328 }
2330 return cast_or_null<ClassTemplateDecl>(
2331 static_cast<const RedeclarableTemplateDecl *>(
2332 this)->getPreviousDecl());
2333 }
2334
2336 return cast<ClassTemplateDecl>(
2337 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2338 }
2340 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2341 }
2342
2344 return cast_or_null<ClassTemplateDecl>(
2346 }
2347
2348 /// Return the partial specialization with the provided arguments if it
2349 /// exists, otherwise return the insertion point.
2352 TemplateParameterList *TPL, void *&InsertPos);
2353
2354 /// Insert the specified partial specialization knowing that it is not
2355 /// already in. InsertPos must be obtained from findPartialSpecialization.
2357 void *InsertPos);
2358
2359 /// Retrieve the partial specializations as an ordered list.
2362
2363 /// Find a class template partial specialization with the given
2364 /// type T.
2365 ///
2366 /// \param T a dependent type that names a specialization of this class
2367 /// template.
2368 ///
2369 /// \returns the class template partial specialization that exactly matches
2370 /// the type \p T, or nullptr if no such partial specialization exists.
2372
2373 /// Find a class template partial specialization which was instantiated
2374 /// from the given member partial specialization.
2375 ///
2376 /// \param D a member class template partial specialization.
2377 ///
2378 /// \returns the class template partial specialization which was instantiated
2379 /// from the given member partial specialization, or nullptr if no such
2380 /// partial specialization exists.
2384
2385 /// Retrieve the template specialization type of the
2386 /// injected-class-name for this class template.
2387 ///
2388 /// The injected-class-name for a class template \c X is \c
2389 /// X<template-args>, where \c template-args is formed from the
2390 /// template arguments that correspond to the template parameters of
2391 /// \c X. For example:
2392 ///
2393 /// \code
2394 /// template<typename T, int N>
2395 /// struct array {
2396 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2397 /// };
2398 /// \endcode
2400
2402 using spec_range = llvm::iterator_range<spec_iterator>;
2403
2405 return spec_range(spec_begin(), spec_end());
2406 }
2407
2409 return makeSpecIterator(getSpecializations(), false);
2410 }
2411
2413 return makeSpecIterator(getSpecializations(), true);
2414 }
2415
2416 // Implement isa/cast/dyncast support
2417 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2418 static bool classofKind(Kind K) { return K == ClassTemplate; }
2419};
2420
2421/// Declaration of a friend template.
2422///
2423/// For example:
2424/// \code
2425/// template <typename T> class A {
2426/// friend class MyVector<T>; // not a friend template
2427/// template <typename U> friend class B; // not a friend template
2428/// template <typename U> friend class Foo<T>::Nested; // friend template
2429/// };
2430/// \endcode
2431///
2432/// \note This class is not currently in use. All of the above
2433/// will yield a FriendDecl, not a FriendTemplateDecl.
2434class FriendTemplateDecl : public Decl {
2435 virtual void anchor();
2436
2437public:
2438 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2439
2440private:
2441 // The number of template parameters; always non-zero.
2442 unsigned NumParams = 0;
2443
2444 // The parameter list.
2445 TemplateParameterList **Params = nullptr;
2446
2447 // The declaration that's a friend of this class.
2448 FriendUnion Friend;
2449
2450 // Location of the 'friend' specifier.
2451 SourceLocation FriendLoc;
2452
2454 TemplateParameterList **Params, unsigned NumParams,
2455 FriendUnion Friend, SourceLocation FriendLoc)
2456 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2457 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2458
2459 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2460
2461public:
2462 friend class ASTDeclReader;
2463
2464 static FriendTemplateDecl *
2467 SourceLocation FriendLoc);
2468
2470
2471 /// If this friend declaration names a templated type (or
2472 /// a dependent member type of a templated type), return that
2473 /// type; otherwise return null.
2475 return Friend.dyn_cast<TypeSourceInfo*>();
2476 }
2477
2478 /// If this friend declaration names a templated function (or
2479 /// a member function of a templated type), return that type;
2480 /// otherwise return null.
2482 return Friend.dyn_cast<NamedDecl*>();
2483 }
2484
2485 /// Retrieves the location of the 'friend' keyword.
2487 return FriendLoc;
2488 }
2489
2491 assert(i <= NumParams);
2492 return Params[i];
2493 }
2494
2495 unsigned getNumTemplateParameters() const {
2496 return NumParams;
2497 }
2498
2499 // Implement isa/cast/dyncast/etc.
2500 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2501 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2502};
2503
2504/// Declaration of an alias template.
2505///
2506/// For example:
2507/// \code
2508/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2509/// \endcode
2511protected:
2513
2516 NamedDecl *Decl)
2517 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2518 Decl) {}
2519
2520 CommonBase *newCommon(ASTContext &C) const override;
2521
2523 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2524 }
2525
2526public:
2527 friend class ASTDeclReader;
2528 friend class ASTDeclWriter;
2529
2530 /// Get the underlying function declaration of the template.
2532 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2533 }
2534
2535
2537 return cast<TypeAliasTemplateDecl>(
2539 }
2541 return cast<TypeAliasTemplateDecl>(
2543 }
2544
2545 /// Retrieve the previous declaration of this function template, or
2546 /// nullptr if no such declaration exists.
2548 return cast_or_null<TypeAliasTemplateDecl>(
2549 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2550 }
2552 return cast_or_null<TypeAliasTemplateDecl>(
2553 static_cast<const RedeclarableTemplateDecl *>(
2554 this)->getPreviousDecl());
2555 }
2556
2558 return cast_or_null<TypeAliasTemplateDecl>(
2560 }
2561
2562 /// Create a function template node.
2565 DeclarationName Name,
2566 TemplateParameterList *Params,
2567 NamedDecl *Decl);
2568
2569 /// Create an empty alias template node.
2572
2573 // Implement isa/cast/dyncast support
2574 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2575 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2576};
2577
2578/// Represents a variable template specialization, which refers to
2579/// a variable template with a given set of template arguments.
2580///
2581/// Variable template specializations represent both explicit
2582/// specializations of variable templates, as in the example below, and
2583/// implicit instantiations of variable templates.
2584///
2585/// \code
2586/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2587///
2588/// template<>
2589/// constexpr float pi<float>; // variable template specialization pi<float>
2590/// \endcode
2592 public llvm::FoldingSetNode {
2593
2594 /// Structure that stores information about a variable template
2595 /// specialization that was instantiated from a variable template partial
2596 /// specialization.
2597 struct SpecializedPartialSpecialization {
2598 /// The variable template partial specialization from which this
2599 /// variable template specialization was instantiated.
2600 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2601
2602 /// The template argument list deduced for the variable template
2603 /// partial specialization itself.
2604 const TemplateArgumentList *TemplateArgs;
2605 };
2606
2607 /// The template that this specialization specializes.
2608 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2609 SpecializedTemplate;
2610
2611 /// Further info for explicit template specialization/instantiation.
2612 /// Does not apply to implicit specializations.
2613 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2614
2615 /// The template arguments used to describe this specialization.
2616 const TemplateArgumentList *TemplateArgs;
2617
2618 /// The point where this template was instantiated (if any).
2619 SourceLocation PointOfInstantiation;
2620
2621 /// The kind of specialization this declaration refers to.
2622 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2623 unsigned SpecializationKind : 3;
2624
2625 /// Whether this declaration is a complete definition of the
2626 /// variable template specialization. We can't otherwise tell apart
2627 /// an instantiated declaration from an instantiated definition with
2628 /// no initializer.
2629 LLVM_PREFERRED_TYPE(bool)
2630 unsigned IsCompleteDefinition : 1;
2631
2632protected:
2634 SourceLocation StartLoc, SourceLocation IdLoc,
2635 VarTemplateDecl *SpecializedTemplate,
2636 QualType T, TypeSourceInfo *TInfo,
2637 StorageClass S,
2639
2640 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2641
2642public:
2643 friend class ASTDeclReader;
2644 friend class ASTDeclWriter;
2645 friend class VarDecl;
2646
2648 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2649 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2650 TypeSourceInfo *TInfo, StorageClass S,
2654
2655 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2656 bool Qualified) const override;
2657
2659 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2660 return cast<VarTemplateSpecializationDecl>(Recent);
2661 }
2662
2663 /// Retrieve the template that this specialization specializes.
2665
2666 /// Retrieve the template arguments of the variable template
2667 /// specialization.
2668 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2669
2670 /// Determine the kind of specialization that this
2671 /// declaration represents.
2673 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2674 }
2675
2678 }
2679
2681 return isExplicitSpecialization() &&
2682 isa<CXXRecordDecl>(getLexicalDeclContext());
2683 }
2684
2685 /// True if this declaration is an explicit specialization,
2686 /// explicit instantiation declaration, or explicit instantiation
2687 /// definition.
2691 }
2692
2694 SpecializationKind = TSK;
2695 }
2696
2697 /// Get the point of instantiation (if any), or null if none.
2699 return PointOfInstantiation;
2700 }
2701
2703 assert(Loc.isValid() && "point of instantiation must be valid!");
2704 PointOfInstantiation = Loc;
2705 }
2706
2707 void setCompleteDefinition() { IsCompleteDefinition = true; }
2708
2709 /// If this variable template specialization is an instantiation of
2710 /// a template (rather than an explicit specialization), return the
2711 /// variable template or variable template partial specialization from which
2712 /// it was instantiated.
2713 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2716 return llvm::PointerUnion<VarTemplateDecl *,
2718
2720 }
2721
2722 /// Retrieve the variable template or variable template partial
2723 /// specialization which was specialized by this.
2724 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2726 if (const auto *PartialSpec =
2727 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2728 return PartialSpec->PartialSpecialization;
2729
2730 return SpecializedTemplate.get<VarTemplateDecl *>();
2731 }
2732
2733 /// Retrieve the set of template arguments that should be used
2734 /// to instantiate the initializer of the variable template or variable
2735 /// template partial specialization from which this variable template
2736 /// specialization was instantiated.
2737 ///
2738 /// \returns For a variable template specialization instantiated from the
2739 /// primary template, this function will return the same template arguments
2740 /// as getTemplateArgs(). For a variable template specialization instantiated
2741 /// from a variable template partial specialization, this function will the
2742 /// return deduced template arguments for the variable template partial
2743 /// specialization itself.
2745 if (const auto *PartialSpec =
2746 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2747 return *PartialSpec->TemplateArgs;
2748
2749 return getTemplateArgs();
2750 }
2751
2752 /// Note that this variable template specialization is actually an
2753 /// instantiation of the given variable template partial specialization whose
2754 /// template arguments have been deduced.
2756 const TemplateArgumentList *TemplateArgs) {
2757 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2758 "Already set to a variable template partial specialization!");
2759 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2760 PS->PartialSpecialization = PartialSpec;
2761 PS->TemplateArgs = TemplateArgs;
2762 SpecializedTemplate = PS;
2763 }
2764
2765 /// Note that this variable template specialization is an instantiation
2766 /// of the given variable template.
2768 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2769 "Previously set to a variable template partial specialization!");
2770 SpecializedTemplate = TemplDecl;
2771 }
2772
2773 /// Retrieve the template argument list as written in the sources,
2774 /// if any.
2776 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2777 return Info->TemplateArgsAsWritten;
2778 return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
2779 }
2780
2781 /// Set the template argument list as written in the sources.
2782 void
2784 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2785 Info->TemplateArgsAsWritten = ArgsWritten;
2786 else
2787 ExplicitInfo = ArgsWritten;
2788 }
2789
2790 /// Set the template argument list as written in the sources.
2794 }
2795
2796 /// Gets the location of the extern keyword, if present.
2798 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2799 return Info->ExternKeywordLoc;
2800 return SourceLocation();
2801 }
2802
2803 /// Sets the location of the extern keyword.
2805
2806 /// Gets the location of the template keyword, if present.
2808 if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2809 return Info->TemplateKeywordLoc;
2810 return SourceLocation();
2811 }
2812
2813 /// Sets the location of the template keyword.
2815
2816 SourceRange getSourceRange() const override LLVM_READONLY;
2817
2818 void Profile(llvm::FoldingSetNodeID &ID) const {
2819 Profile(ID, TemplateArgs->asArray(), getASTContext());
2820 }
2821
2822 static void Profile(llvm::FoldingSetNodeID &ID,
2823 ArrayRef<TemplateArgument> TemplateArgs,
2824 const ASTContext &Context) {
2825 ID.AddInteger(TemplateArgs.size());
2826 for (const TemplateArgument &TemplateArg : TemplateArgs)
2827 TemplateArg.Profile(ID, Context);
2828 }
2829
2830 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2831
2832 static bool classofKind(Kind K) {
2833 return K >= firstVarTemplateSpecialization &&
2834 K <= lastVarTemplateSpecialization;
2835 }
2836};
2837
2840 /// The list of template parameters
2841 TemplateParameterList *TemplateParams = nullptr;
2842
2843 /// The variable template partial specialization from which this
2844 /// variable template partial specialization was instantiated.
2845 ///
2846 /// The boolean value will be true to indicate that this variable template
2847 /// partial specialization was specialized at this level.
2848 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2849 InstantiatedFromMember;
2850
2852 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2854 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2856
2858 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2859 Context),
2860 InstantiatedFromMember(nullptr, false) {}
2861
2862 void anchor() override;
2863
2864public:
2865 friend class ASTDeclReader;
2866 friend class ASTDeclWriter;
2867
2869 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2871 VarTemplateDecl *SpecializedTemplate, QualType T,
2872 TypeSourceInfo *TInfo, StorageClass S,
2874
2877
2879 return cast<VarTemplatePartialSpecializationDecl>(
2880 static_cast<VarTemplateSpecializationDecl *>(
2881 this)->getMostRecentDecl());
2882 }
2883
2884 /// Get the list of template parameters
2886 return TemplateParams;
2887 }
2888
2889 /// \brief All associated constraints of this partial specialization,
2890 /// including the requires clause and any constraints derived from
2891 /// constrained-parameters.
2892 ///
2893 /// The constraints in the resulting list are to be treated as if in a
2894 /// conjunction ("and").
2896 TemplateParams->getAssociatedConstraints(AC);
2897 }
2898
2900 return TemplateParams->hasAssociatedConstraints();
2901 }
2902
2903 /// \brief Retrieve the member variable template partial specialization from
2904 /// which this particular variable template partial specialization was
2905 /// instantiated.
2906 ///
2907 /// \code
2908 /// template<typename T>
2909 /// struct Outer {
2910 /// template<typename U> U Inner;
2911 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2912 /// };
2913 ///
2914 /// template int* Outer<float>::Inner<int*>;
2915 /// \endcode
2916 ///
2917 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2918 /// end up instantiating the partial specialization
2919 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2920 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2921 /// \c Outer<float>::Inner<U*>, this function would return
2922 /// \c Outer<T>::Inner<U*>.
2924 const auto *First =
2925 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2926 return First->InstantiatedFromMember.getPointer();
2927 }
2928
2929 void
2931 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2932 First->InstantiatedFromMember.setPointer(PartialSpec);
2933 }
2934
2935 /// Determines whether this variable template partial specialization
2936 /// was a specialization of a member partial specialization.
2937 ///
2938 /// In the following example, the member template partial specialization
2939 /// \c X<int>::Inner<T*> is a member specialization.
2940 ///
2941 /// \code
2942 /// template<typename T>
2943 /// struct X {
2944 /// template<typename U> U Inner;
2945 /// template<typename U> U* Inner<U*> = (U*)(0);
2946 /// };
2947 ///
2948 /// template<> template<typename T>
2949 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2950 /// \endcode
2952 const auto *First =
2953 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2954 return First->InstantiatedFromMember.getInt();
2955 }
2956
2957 /// Note that this member template is a specialization.
2959 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2960 assert(First->InstantiatedFromMember.getPointer() &&
2961 "Only member templates can be member template specializations");
2962 return First->InstantiatedFromMember.setInt(true);
2963 }
2964
2965 SourceRange getSourceRange() const override LLVM_READONLY;
2966
2967 void Profile(llvm::FoldingSetNodeID &ID) const {
2969 getASTContext());
2970 }
2971
2972 static void
2973 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2974 TemplateParameterList *TPL, const ASTContext &Context);
2975
2976 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2977
2978 static bool classofKind(Kind K) {
2979 return K == VarTemplatePartialSpecialization;
2980 }
2981};
2982
2983/// Declaration of a variable template.
2985protected:
2986 /// Data that is common to all of the declarations of a given
2987 /// variable template.
2989 /// The variable template specializations for this variable
2990 /// template, including explicit specializations and instantiations.
2991 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
2992
2993 /// The variable template partial specializations for this variable
2994 /// template.
2995 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
2997
2998 Common() = default;
2999 };
3000
3001 /// Retrieve the set of specializations of this variable template.
3002 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3003 getSpecializations() const;
3004
3005 /// Retrieve the set of partial specializations of this class
3006 /// template.
3007 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3009
3012 NamedDecl *Decl)
3013 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3014
3015 CommonBase *newCommon(ASTContext &C) const override;
3016
3018 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3019 }
3020
3021public:
3022 friend class ASTDeclReader;
3023 friend class ASTDeclWriter;
3024
3025 /// Load any lazily-loaded specializations from the external source.
3026 void LoadLazySpecializations() const;
3027
3028 /// Get the underlying variable declarations of the template.
3030 return static_cast<VarDecl *>(TemplatedDecl);
3031 }
3032
3033 /// Returns whether this template declaration defines the primary
3034 /// variable pattern.
3037 }
3038
3040
3041 /// Create a variable template node.
3044 TemplateParameterList *Params,
3045 VarDecl *Decl);
3046
3047 /// Create an empty variable template node.
3049
3050 /// Return the specialization with the provided arguments if it exists,
3051 /// otherwise return the insertion point.
3053 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3054
3055 /// Insert the specified specialization knowing that it is not already
3056 /// in. InsertPos must be obtained from findSpecialization.
3057 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3058
3060 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3061 }
3063 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3064 }
3065
3066 /// Retrieve the previous declaration of this variable template, or
3067 /// nullptr if no such declaration exists.
3069 return cast_or_null<VarTemplateDecl>(
3070 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3071 }
3073 return cast_or_null<VarTemplateDecl>(
3074 static_cast<const RedeclarableTemplateDecl *>(
3075 this)->getPreviousDecl());
3076 }
3077
3079 return cast<VarTemplateDecl>(
3080 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3081 }
3083 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3084 }
3085
3087 return cast_or_null<VarTemplateDecl>(
3089 }
3090
3091 /// Return the partial specialization with the provided arguments if it
3092 /// exists, otherwise return the insertion point.
3095 TemplateParameterList *TPL, void *&InsertPos);
3096
3097 /// Insert the specified partial specialization knowing that it is not
3098 /// already in. InsertPos must be obtained from findPartialSpecialization.
3100 void *InsertPos);
3101
3102 /// Retrieve the partial specializations as an ordered list.
3105
3106 /// Find a variable template partial specialization which was
3107 /// instantiated
3108 /// from the given member partial specialization.
3109 ///
3110 /// \param D a member variable template partial specialization.
3111 ///
3112 /// \returns the variable template partial specialization which was
3113 /// instantiated
3114 /// from the given member partial specialization, or nullptr if no such
3115 /// partial specialization exists.
3118
3120 using spec_range = llvm::iterator_range<spec_iterator>;
3121
3123 return spec_range(spec_begin(), spec_end());
3124 }
3125
3127 return makeSpecIterator(getSpecializations(), false);
3128 }
3129
3131 return makeSpecIterator(getSpecializations(), true);
3132 }
3133
3134 // Implement isa/cast/dyncast support
3135 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3136 static bool classofKind(Kind K) { return K == VarTemplate; }
3137};
3138
3139/// Declaration of a C++20 concept.
3140class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3141protected:
3143
3146 : TemplateDecl(Concept, DC, L, Name, Params),
3148public:
3151 TemplateParameterList *Params,
3154
3156 return ConstraintExpr;
3157 }
3158
3159 SourceRange getSourceRange() const override LLVM_READONLY {
3160 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3162 }
3163
3164 bool isTypeConcept() const {
3165 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3166 }
3167
3169 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3170 }
3172 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3173 }
3174
3175 // Implement isa/cast/dyncast/etc.
3176 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3177 static bool classofKind(Kind K) { return K == Concept; }
3178
3179 friend class ASTReader;
3180 friend class ASTDeclReader;
3181 friend class ASTDeclWriter;
3182};
3183
3184// An implementation detail of ConceptSpecialicationExpr that holds the template
3185// arguments, so we can later use this to reconstitute the template arguments
3186// during constraint checking.
3188 : public Decl,
3189 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3190 TemplateArgument> {
3191 unsigned NumTemplateArgs;
3192
3194 ArrayRef<TemplateArgument> ConvertedArgs);
3195 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3196
3197public:
3200 ArrayRef<TemplateArgument> ConvertedArgs);
3203 unsigned NumTemplateArgs);
3204
3206 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3207 NumTemplateArgs);
3208 }
3210
3211 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3212 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3213
3215 friend class ASTDeclReader;
3216};
3217
3218/// A template parameter object.
3219///
3220/// Template parameter objects represent values of class type used as template
3221/// arguments. There is one template parameter object for each such distinct
3222/// value used as a template argument across the program.
3223///
3224/// \code
3225/// struct A { int x, y; };
3226/// template<A> struct S;
3227/// S<A{1, 2}> s1;
3228/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3229/// \endcode
3231 public Mergeable<TemplateParamObjectDecl>,
3232 public llvm::FoldingSetNode {
3233private:
3234 /// The value of this template parameter object.
3235 APValue Value;
3236
3238 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3239 T),
3240 Value(V) {}
3241
3243 const APValue &V);
3244 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3246
3247 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3248 /// create these.
3249 friend class ASTContext;
3250 friend class ASTReader;
3251 friend class ASTDeclReader;
3252
3253public:
3254 /// Print this template parameter object in a human-readable format.
3255 void printName(llvm::raw_ostream &OS,
3256 const PrintingPolicy &Policy) const override;
3257
3258 /// Print this object as an equivalent expression.
3259 void printAsExpr(llvm::raw_ostream &OS) const;
3260 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3261
3262 /// Print this object as an initializer suitable for a variable of the
3263 /// object's type.
3264 void printAsInit(llvm::raw_ostream &OS) const;
3265 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3266
3267 const APValue &getValue() const { return Value; }
3268
3269 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3270 const APValue &V) {
3271 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3272 V.Profile(ID);
3273 }
3274 void Profile(llvm::FoldingSetNodeID &ID) {
3275 Profile(ID, getType(), getValue());
3276 }
3277
3279 return getFirstDecl();
3280 }
3282 return getFirstDecl();
3283 }
3284
3285 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3286 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3287};
3288
3290 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3291 return PD;
3292 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3293 return PD;
3294 return P.get<TemplateTemplateParmDecl *>();
3295}
3296
3298 auto *TD = dyn_cast<TemplateDecl>(D);
3299 return TD && (isa<ClassTemplateDecl>(TD) ||
3300 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3301 isa<TypeAliasTemplateDecl>(TD) ||
3302 isa<TemplateTemplateParmDecl>(TD))
3303 ? TD
3304 : nullptr;
3305}
3306
3307/// Check whether the template parameter is a pack expansion, and if so,
3308/// determine the number of parameters produced by that expansion. For instance:
3309///
3310/// \code
3311/// template<typename ...Ts> struct A {
3312/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3313/// };
3314/// \endcode
3315///
3316/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3317/// is not a pack expansion, so returns an empty Optional.
3318inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3319 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3320 if (TTP->isExpandedParameterPack())
3321 return TTP->getNumExpansionParameters();
3322 }
3323
3324 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3325 if (NTTP->isExpandedParameterPack())
3326 return NTTP->getNumExpansionTypes();
3327 }
3328
3329 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3330 if (TTP->isExpandedParameterPack())
3331 return TTP->getNumExpansionTemplateParameters();
3332 }
3333
3334 return std::nullopt;
3335}
3336
3337/// Internal helper used by Subst* nodes to retrieve the parameter list
3338/// for their AssociatedDecl.
3339TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3340
3341} // namespace clang
3342
3343#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:3285
int Id
Definition: ASTDiff.cpp:190
StringRef P
static char ID
Definition: Arena.cpp:183
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.
SourceLocation Loc
Definition: SemaObjC.cpp:755
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:182
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
bool isConstrained() const
Definition: Type.h:6001
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:549
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition: DeclCXX.cpp:1905
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.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
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.
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.
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.
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:128
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:908
Kind getKind() const
Definition: DeclBase.h:448
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:433
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
Storage for a default argument.
Definition: DeclTemplate.h:299
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
Definition: DeclTemplate.h:360
bool isSet() const
Determine whether there is a default argument for this parameter.
Definition: DeclTemplate.h:326
ArgType get() const
Get the default argument's value.
Definition: DeclTemplate.h:334
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:354
void clear()
Remove the default argument, even if it was inherited.
Definition: DeclTemplate.h:380
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
Definition: DeclTemplate.h:345
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
Definition: DeclTemplate.h:330
Provides information about a dependent function-template specialization declaration.
Definition: DeclTemplate.h:689
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
Definition: DeclTemplate.h:708
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:701
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:222
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Definition: DeclTemplate.h:229
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:1971
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2283
Declaration of a template function.
Definition: DeclTemplate.h:957
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:979
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.
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:971
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:467
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
Definition: DeclTemplate.h:481
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:542
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
Definition: DeclTemplate.h:604
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
Definition: DeclTemplate.h:522
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
Definition: DeclTemplate.h:593
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:485
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
Definition: DeclTemplate.h:553
void Profile(llvm::FoldingSetNodeID &ID)
Definition: DeclTemplate.h:599
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
Definition: DeclTemplate.h:489
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
Definition: DeclTemplate.h:519
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:525
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
Definition: DeclTemplate.h:559
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
Definition: DeclTemplate.h:536
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:615
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:646
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:637
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
Definition: DeclTemplate.h:655
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
Definition: DeclTemplate.h:625
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Definition: DeclTemplate.h:660
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
Definition: DeclTemplate.h:634
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
Definition: Redeclarable.h:314
TemplateParamObjectDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:320
This represents a decl that may have a name.
Definition: Decl.h:249
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.
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.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
void setDefaultArgument(Expr *DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
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)
Represents a pack expansion of types.
Definition: Type.h:6570
A (possibly-)qualified type.
Definition: Type.h:940
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
Definition: DeclTemplate.h:768
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:823
redeclarable_base::redecl_iterator redecl_iterator
Definition: DeclTemplate.h:925
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:860
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:838
redeclarable_base::redecl_range redecl_range
Definition: DeclTemplate.h:924
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:813
static bool classof(const Decl *D)
Definition: DeclTemplate.h:935
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
Definition: DeclTemplate.h:907
static bool classofKind(Kind K)
Definition: DeclTemplate.h:937
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:835
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
Definition: DeclTemplate.h:865
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
Definition: DeclTemplate.h:911
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
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:216
RedeclarableTemplateDecl * getNextRedeclaration() const
Definition: Redeclarable.h:189
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:292
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:223
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:296
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:450
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:350
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3682
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:244
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
Definition: DeclTemplate.h:283
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:271
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:280
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:265
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
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:394
NamedDecl * TemplatedDecl
Definition: DeclTemplate.h:444
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:445
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
Definition: DeclTemplate.h:453
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:438
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
Definition: DeclTemplate.h:404
void setTemplateParameters(TemplateParameterList *TParams)
Definition: DeclTemplate.h:448
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:432
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
static bool classofKind(Kind K)
Definition: DeclTemplate.h:434
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:134
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:203
const_iterator begin() const
Definition: DeclTemplate.h:132
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:185
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:107
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
Definition: DeclTemplate.h:172
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:129
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:180
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
Definition: DeclTemplate.h:201
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
Definition: DeclTemplate.h:148
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
Definition: DeclTemplate.h:200
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
Definition: DeclTemplate.h:103
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:139
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:199
ArrayRef< const NamedDecl * > asArray() const
Definition: DeclTemplate.h:140
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.
QualType 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.
TypeSourceInfo * getDefaultArgumentInfo() const
Retrieves the default argument's source information, if any.
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.
void setDefaultArgument(TypeSourceInfo *DefArg)
Set the default argument for 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)
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:3555
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:231
Represents a declaration of a type.
Definition: Decl.h:3390
const Type * getTypeForDecl() const
Definition: Decl.h:3414
A container of type source information.
Definition: Type.h:7331
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7342
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2759
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8127
A set of unresolved declarations.
Definition: UnresolvedSet.h:61
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2257
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:2756
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...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
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
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
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.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition: Specifiers.h:209
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition: Decl.cpp:77
NamedDecl * getAsNamedDecl(TemplateParameter P)
StorageClass
Storage classes.
Definition: Specifiers.h:245
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:6300
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:302
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:185
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ 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:216
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Definition: Format.h:5428
#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:963
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:966
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:792
GlobalDeclID * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:799
TemplateArgument * InjectedArgs
The set of "injected" template arguments used within this template.
Definition: DeclTemplate.h:808
static ArrayRef< TemplateArgument > getTemplateArgs(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:951
static DeclType * getDecl(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:946
static ArrayRef< TemplateArgument > getTemplateArgs(EntryType *D)
Definition: DeclTemplate.h:740
static DeclType * getDecl(EntryType *D)
Definition: DeclTemplate.h:736
SpecIterator(typename llvm::FoldingSetVector< EntryType >::iterator SetIter)
Definition: DeclTemplate.h:755
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 ...